一道整數求值作業


題目描述:給定一個整數 X,找到組成的數字和 X 完全相同的,且大於 X 的最小的那個數。

  • 輸入要求

    一個整數 X,不會以0開頭。

  • 輸出要求

    輸出與 X 數字組成完全相同,且大於 X 的最小的數。若不存在這樣的數,輸出 0

  • 例如,輸入 156 輸出 165,或者 27711 就是 71127,330 的話就是 0

思路:題目有三大約束:a. 組成與 X 相同  b. 大於 X  c. 最小

針對 a,可以交換 X 的各個位;對於 b,變動的最高位必須比原來大;對於 c,變動的最高位越接近個位越好

1. 暴力法

窮舉所有可能的數,然后在大於 X 的里面找最小

2. 反向掃描

從個位開始逆向遍歷,向后掃描,找出比自己大的所有位,選擇其中最小的,交換之,然后排序,done

如字符串 s="263861",序號為 0~5
s[4] = 6,后面沒有比自己大的
s[3] = 8,同上
s[2] = 3,后面比自己大但最小的數是 6,交換 s[2]和s[4]
從小到大排序 s[3]~s[5]   [注]:因為當前字符后的序列總是降序的,且交換后仍可保持降序,充分利用這一點能有效提高算法效率。故此處無需排序。
所以,最終結果為 266138

實現:

#!/usr/bin/env python
#coding=utf8

def test(num):
    text = str(num)
    rtext = list(text[::-1]) #反轉字符串以方便遍歷
    for i in xrange(1, len(rtext)):
        if rtext[i] < rtext[i-1]: #減少無效比較次數
            gts = [x for x in rtext[:i] if x > rtext[i]] #找到比自己大的所有位
            j = rtext.index(min(gts)) #選擇其中最小的
            rtext[i], rtext[j] = rtext[j], rtext[i] #交換之
            return ''.join(rtext[i:][::-1] + rtext[:i])
    return '0'

if __name__ == "__main__":
    from timeit import Timer
    num = input("Input a number: ")
    t1 = Timer("test(num)", "from __main__ import test, num")
    print t1.timeit(1000) #運行1000次所需秒數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM