摘要:從位向右,找到比小的最大的那個數(shù),并與交換。交換后,把位向右注意是的,不是的值的所有數(shù)字降序排列。對于來說,從右向左可以分割為,,,這三種情況都是最小排列。
題目如下:
給定某一個正整數(shù),組成這個數(shù)的數(shù)字不變,返回下一個比它小的數(shù),如:
nextSmaller(21) == 12 nextSmaller(531) == 513 nextSmaller(907) == 790 nextSmaller(51226262651257) == 51226262627551
如果沒有下一個比它小的數(shù)字,或者下一個比它小的數(shù)字以0開頭,則返回-1,如:
nextSmaller(9) == -1 nextSmaller(111) == -1 nextSmaller(135) == -1 nextSmaller(1027) == -1 // 0721以0開頭,所以返回-1算法描述(找到下一個比它小的數(shù)):
1.find pivot:這個數(shù)從右往左,一位位地來比較,如果第i位的數(shù)字,比第i+1位的數(shù)字大,則把第i位的數(shù)字置為pivot(標志位)。
2.swap:從pivot位向右,找到比pivot小的最大的那個數(shù),并與pivot交換。
3.sort:交換后,把pivot位向右(注意是pivot的index,不是pivot的值)的所有數(shù)字降序排列。
這樣,新得到的數(shù)就是下一個比它小的數(shù)。
比如我們拿54123來分析。
1.find pivot:從最右邊的3來看,因為3沒有第i+1位數(shù)字(3沒有右邊),所以左移一位到2;2比右邊的3小,所以繼續(xù)左移一位到1;同理,1也比2要小,所以繼續(xù)左移一位到4;4比1要大了,那么把4置為pivot,這時停止。
2.swap:現(xiàn)在4是pivot,那么從4向右,有1,2,3三個數(shù)字,并且都比4小,這其中3是最大的,所以把4和3的位置交換,得到53124。
3.sort:交換后,pivot位上是3,把3往右的所有數(shù)字降序排列,得到53421,這就是下一個比54123小的數(shù)。
下面是我自己思考的為什么,不一定對。
對于每個數(shù),它最小的排列只有1種情況,就是權(quán)位從高到低,數(shù)字從小到大排列。
比如123的最小排列就是123。
對于54123來說,從右向左可以分割為3,23,123,這三種情況都是最小排列。
也就是說,如果我們只對3或者23或者123進行重組,是沒有變化的。
于是再向左進行分割,得到5和4123,發(fā)現(xiàn)4123已經(jīng)不再是最小排列了,換句話說4123肯定有下一個比它小的數(shù),就把4標記出來,對4123進行重組。
怎么重組呢?最高的權(quán)位,放上比4稍小的,也就是3,然后對于3xxx的后三位,放上值最大的情況,就是412的降序排列421,這樣就能保證“3421是4123的上一個數(shù)”。
這個算法一句話總結(jié):對于某個數(shù),從右向左找它的子列,如果子列是最小排列,那子列沒法重組,繼續(xù)向右;如果子列不是最小排列,就對子列進行重組。
感覺算法里,“分治”加“pivot(標志位)”的解法很常用啊,把復(fù)雜情況分成最簡單的子情況,如果符合規(guī)律,那么子情況擴充,如果不符合規(guī)律,那么置上標志位,再進行考慮。
下面是寫得不怎么樣的代碼:function nextSmaller(num) { var arr = []; (num + "").split("").forEach(function (val) { arr.push(parseInt(val)); }); // 1st: find the pivot, if digit is greater than its right digit, it becomes a pivot var pivot = -1; for(var i = arr.length - 2; i >= 0;i--) { if (arr[i] > arr[i + 1]) { pivot = i; break; } if (i == 0) { return -1; } } // 2nd: find the least less than the pivot, and swap them var swap = -1; for (i = pivot + 1;i < arr.length;i++) { if (swap < 0) { if (arr[i] < arr[pivot]) { swap = i; } } else { if (arr[i] < arr[pivot] && arr[i] > arr[swap]) { swap = i } } } var _mem; _mem = arr[pivot]; arr[pivot] = arr[swap]; arr[swap] = _mem; if (arr[0] == 0) { return -1; } // 3rd: sort the right of pivot, decreasingly var firstArray = arr.slice(0, pivot + 1); var secondArray = arr.slice(pivot + 1); secondArray.sort(function (a, b) { return b -a; }); // 4th: return val var result = (firstArray.concat(secondArray)).join(""); if (result == num){ return - 1 } return parseInt(result); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81103.html
摘要:遇到的坑剛拿到這道題就直接做了這樣的判斷,可是萬一是這個判斷就是錯誤的了。思路二上述算法遍歷了兩次鏈表,還額外申請了一個數(shù)組空間,效率不高,不如直接就地反轉(zhuǎn)鏈表,更改每個節(jié)點自身的指針。 2018.10.14 來源:劍指offer 題目:反轉(zhuǎn)鏈表 輸入一個鏈表,反轉(zhuǎn)鏈表后,輸出新鏈表的表頭。思路一:把所有鏈表內(nèi)容都輸入到一個數(shù)組,再次遍歷鏈表,得到數(shù)組反轉(zhuǎn)后的值,最后輸出原來的head...
摘要:但是題目非要弄成鏈表的形式,說實在的,我真沒有見過前端什么地方還需要用鏈表這種結(jié)構(gòu)的除了面試的時候,所以說這種題目對于實際工作是沒什么用處的,但是腦筋急轉(zhuǎn)彎的智商題既然這樣出了,我們就來看看怎么解決它吧。 今天在知乎上看到一個回答《為什么前端工程師那么難招?》,作者提到說有很多前端工程師甚至連單鏈表翻轉(zhuǎn)都寫不出來。說實話,來面試的孩子們本來就緊張,你要冷不丁問一句單鏈表翻轉(zhuǎn)怎么寫,估計...
摘要:規(guī)則使用語言,讓函數(shù)獲取傳遞的參數(shù)并返回字符串中的最大單詞。忽略字符串中標點符號并假設(shè)不會為空。測試用例思路通過過濾字符串,并把字符串根據(jù)空格符轉(zhuǎn)換成字符串數(shù)組通過循環(huán)把獲取字符串數(shù)組中的長度最長的字符串 雖然都是很簡單的算法,每個都只需5分鐘左右,但寫起來總會遇到不同的小問題,希望大家能跟我一起每天進步一點點。更多的小算法練習(xí),可以查看我的文章。 規(guī)則 Using the JavaS...
摘要:對于這種會退出的情況,數(shù)組顯然不能像鏈表一樣直接斷開,因此采用標記法先生成一個長度為的布爾型數(shù)組,用填充。中對整個進行遍歷才能得到此時數(shù)組中的數(shù)量。 文中的速度測試部分,時間是通過簡單的 System.currentTimeMillis() 計算得到的, 又由于 Java 的特性,每次測試的結(jié)果都不一定相同, 對于低數(shù)量級的情況有 ± 20 的浮動,對于高數(shù)量級的情況有的能有 ± 10...
摘要:前言數(shù)據(jù)結(jié)構(gòu)與算法專題會不定時更新,歡迎各位讀者監(jiān)督。指針反轉(zhuǎn)實現(xiàn)鏈表反轉(zhuǎn)代碼反轉(zhuǎn)鏈表獲取當前下下個元素測試代碼部分用到了上篇文章數(shù)據(jù)結(jié)構(gòu)與算法鏈表的代碼段,請移步獲取。 聲明:碼字不易,轉(zhuǎn)載請注明出處,歡迎文章下方討論交流。 前言:Java數(shù)據(jù)結(jié)構(gòu)與算法專題會不定時更新,歡迎各位讀者監(jiān)督。本文是上篇文章Java數(shù)據(jù)結(jié)構(gòu)與算法——鏈表的擴展篇,介紹鏈表的特點,使用場景、鏈表的性能分析以...
閱讀 3532·2021-09-27 13:35
閱讀 3571·2019-08-29 17:09
閱讀 2450·2019-08-26 11:30
閱讀 711·2019-08-26 10:32
閱讀 545·2019-08-26 10:23
閱讀 1206·2019-08-26 10:20
閱讀 3161·2019-08-23 15:26
閱讀 3571·2019-08-23 14:33