題目要求如下:
如果乙個數字十進位制表達時,不存在連續兩位相同,則稱之為「不重複數」。例如,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...