面試題解:輸入一個數A,找到大於A的一個最小數B,且B中不存在連續相等的兩個數字

玄魂發表於2018-08-27

玄魂工作室祕書 [玄魂工作室]

昨天發的演算法有一處情況沒考慮到,比如加一後有進位,導致又出現重複數字的情況,修正後今天重新發一次。

比如輸入99,那B應該是101 因為100有兩個連續相當的0。

基本思路:最壞的辦法 加1一直加1 直到找到有不重複的數為止。

面試:這道題要是作為面試題的話,要跟面試官確認好,數A的範圍,比如是否有小數是否有負數,等等。在這裡我們把題確定為正數。

優化思路:

如果輸入的數本身不存在重複,則加1;如果存在重複,比如我們輸入的是11100234,那如果要找比11100234大的最小沒有重複的數,最先重複的兩位數是11,那麼如果想讓11不重複並且比11100234大,那麼應該讓第二位的1加1 變成12100234。然後為了讓數字最小,則把2後面的數字都變成0,變成12000000;然後在從2後開始找不重複數,00重複,變成01;所以結果是12010101。這裡需要注意:如果變化後又進位的情況,還需要重新處理一遍,比如199,第一遍處理後變成了200,200還是有重複,則需要重新處理。

# -*- coding: utf-8 -*-
"""
題目:輸入一個數A,找到大於A的一個最小數B,且B中不存在連續相當的兩個數字。
比如輸入99,那B應該是101 因為100有兩個連續相當的0
基本思路:最壞的辦法 加1一直加1 直到找到有不重複的數為止
優化的思路 如果輸入是1099 加1後變成1100,那麼他下一個不重複的數如果一直加1效率就會比較低,這是可以優化的點
這道題要是作為面試提的話,要跟面試官確認好,數A的範圍,比如是否有小數
是否有負數,等等。在這裡我們把題確定為正數
"""

def get_data(num):
    """
    獲取num個10相乘的數字,為了讓重複的數字加1,比如num=4 則返回10000
    args:需要0的個數
    """
    data = 1
    while num > 0:
        data = data * 10
        num = num -1
    return data

def get_tail(num, data):
    """
    獲取data的後面num個數,比如data=1345 num=3 則返回345
    args:num需要取後幾位 data數字
    """
    list_data = []
    #獲取到num位0的數字
    head = get_data(num)
    #用抹除的方式獲取後幾位
    need_data = data % head
    return need_data

def judge(data):
    """
    判斷data中是否有連續重複數字
    args:data數字
    """

    i = 1
    while i < len(data):  
        #判斷是否有兩個數字相等
        if string_num[i-1] == string_num[i]:

            return True
        i = i + 1
    return False

if __name__ == "__main__":  
    #輸入的數字 
    num = 1099
    num = num + 1
    #數字轉字串,為了判斷是否有相等的數字
    string_num = str(num)   


    i = 1
    flag = 0 
    while True:  
        if(judge(string_num)==False):
            break
        while i < len(string_num):  
            #判斷是否有兩個數字相等
            if string_num[i-1] == string_num[i]:
                #如果有重複的數字,則把重複的兩個數,中小的一位數字加1,然後在把後面的位置0
                new_len = len(string_num) - i - 1
                num = num + get_data(new_len)
                tail = get_tail(new_len, num)
                #置0的辦法是用num減掉後面的幾位數
                num = num - tail
                string_num = str(num)

                flag = 1
            #置0後 在找後面幾位去找不重複的最小數
            i = i + 1 
        #如果flag=0 證明沒有重複的 證明找到了不重複的數字,則退出 
        if flag == 0:
            num = num + 1
            string_num = str(num)

        #如果flag=0 並且運算到了最後一位
        if flag == 1 and i >=len(string_num):
            #在判斷下是否有重複,如果有重新算,沒有則停止
            if(judge(string_num)):
                i = 0
                flag = 0 
                continue
            else:
                break

    print  string_num  
複製程式碼

1099輸出是:1201 ; 99 輸出是:101; 9 輸出是:10 ;1098 輸出是:1201

更多演算法內容,歡迎關注 訂閱號“白話演算法:

image

Python演算法與資料結構--求所有子陣列的和的最大值

把搜尋樹轉成雙向連結串列

優秀演算法教程推薦

相關文章