真正的不重複數字實現,像人一樣去程式設計

2021-09-05 21:37:08 字數 1580 閱讀 1258

題目要求如下:

如果乙個數字十進位制表達時,不存在連續兩位相同,則稱之為「不重複數」。例如,105、164和198都是「不重複數」,而11、100和122不是。實現乙個函式,用乙個long型別( long型別數字a),實現返回大於a的最小「不重複數」。

看到兩個朋友在做這個演算法題

夏小冰的**,運算時1122, 18, 21,123, 98都有正確結果,但是100011,121989999的答案是錯的

winzheng的結果如下

a=1122, 18, 21,123, 98,100011,121989999

結果:1201,19,23,124,101,101010,123010101

看起來功能都是實現了

但是仔細看**他是把輸入的a不斷加1,並且判斷結果的數字是否符合要求?

//只要是乙個人,就不會這麼去做的(sorry,兄弟)

*其實我們在程式設計的時候更多的要從自身角度出發。從問題的固有規律出發,設想乙個人是如何來解決這個問題的。並且把解決問題的步驟轉化為程式,就能寫出比較好的演算法了。

想想如果給乙個人乙個100位長的數字,他會用這種不斷加1的辦法來解決問題嗎?

《程式設計之美》

這個是winzheng的標題,不過從他的**裡只能感受到對cpu無情的蹂躪。

以至於如果資料更大,例如:121989999991999,花了好幾分鐘也沒算出來,這個時候真的需要考慮時間複雜度等問題了。

解決這個問題只要把計算機當人看就可以了

1、將輸入數加1

2、人類會從最高位的下一位作為當前位開始逐位尋找相鄰的連續數,如果沒有,則該數字就是目標值

3、如果當前位和前一位相同,把當前位的數字加1

3.1 如果加1後導致進製,則當前位等於前一位,前一位加1,返回3.1

3.2 加1後不進製,返回原始數字最高位到當前位的資料,後續拼接上「0101…」組成的剩餘部分即可

3.3 進製到最高位,則返回1,後續拼接上「0101…」組成的剩餘部分即可

**如下

public static long getnextnotduplicatedvalue4(long a)

}//加1後不進製(i != 0),返回原始數字最高位到當前位的資料,後續拼接上「0101…」組成的剩餘部分即可

//進製到最高位(i == 0),則返回1,後續拼接上「0101…」組成的剩餘部分即可

string t = i == 0 ? "1" : new string(arr.takewhile((item, index) => index <= i).toarray());

return long.parse(t + makestring2(arr.length - i-math.sign(i)*1)); }}

//如果沒有,則該數字就是目標值

return a;

}執行速度僅和a的位數部分相關

計算121989999991999也是瞬間的

總結:

把計算機當親兄弟來看待,雖然他傻得只會不知疲倦得做加法

另外:

演算法絕不是書上學來的那幾種

環顧一下四周,想想人類是如何改變世界的,然後再讓計算機兄弟來幫忙

測試資料也是非常重要的乙個東西

改登錄檔,實現像迅雷一樣的自定義url

改登錄檔,實現像迅雷一樣的自定義url hkey classes root myurl myurl url protocol hkey classes root myurl defaulticon c myurlexe.exe hkey classes root myurl shell open h...

C 實現像微信PC版一樣的掃碼登入功能

現在好些 都支援掃碼登入,感覺上安全了很多,但是本地程式掃碼登入的不多,就用c 實現了一下,需要作如下準備 在應用中建立乙個應用,這個是關鍵,我們掃碼就是和它有關.下面轉到c 這裡,登入介面上放乙個webbrowser控制項,用於顯示掃碼登入鏈結,再放乙個控制項用於顯示 等使用者掃了 後就跳轉到自己...

刪除完全一樣的重複資料, 保留其中一條

1.刪除已存在表.if exists select 1 from sysobjects where id object id n test and objectproperty id,n isusertable 1 begin drop table test end go 2.建表 create t...