31. Next Permutation

Description:

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,31,3,2
3,2,11,2,3
1,1,51,5,1

Solutions:

Approach 1: Optimized solution with time complexity of O(n)

我們首先必須明白“next permutation”的含義是什么钻注。題目中的例子給了我們提示信息,例如對于數(shù)組[1, 2, 3]來說配猫,它的一個全排列是

1, 2, 3
1, 3, 2
2, 1, 3
2, 3, 1
3, 1, 2
3, 2, 1

故對于排列2, 1, 3幅恋, 它的下一個排列便是2, 3, 1,再下一個排列便是3, 1, 2泵肄。如果當(dāng)前排列已經(jīng)是全排列的最后一種如3, 2, 1捆交,則下一個排列應(yīng)該是正序排列, 即1, 2, 3腐巢。
但是對于有相同數(shù)字的數(shù)組品追,例如[1, 1, 1, 1, 5]來說,它的全排列為

1, 1, 1, 1, 5
1, 1, 1, 5, 1
1, 1, 5, 1, 1
1, 5, 1, 1, 1
5, 1, 1, 1, 1

通過觀察上述排列冯丙,我們發(fā)現(xiàn)肉瓦,如果把其中的逗號去除,把它們看成數(shù)字胃惜,則第n個排列組成的數(shù)比第n-1的要大泞莉,比n+1的要小。
因此船殉,求下一個排列鲫趁,即求由比這個數(shù)大的下一個排列。

有了這個思路捺弦,我們的算法可如下設(shè)計:

  1. 從左向右遍歷數(shù)組饮寞,直到找到正序的兩個數(shù)nums[i-1], nums[i]使得num[i-1] < nums[i],此時我們可保證nums[i...n-1]是逆序的列吼。
  2. nums[i...n-1]中幽崩,從左向右遍歷數(shù)組,找到比num[i-1]大的第一個數(shù)nums[j]使得nums[j] > nums[i]寞钥,該數(shù)即是nums[i...n-1]中比nums[i-1]大的最小的數(shù)慌申。
  3. 由于我們要找到比當(dāng)前排列大的下一個組合,且nums[i...n-1]是逆序的理郑。故nums[i...n-1]該子序列已經(jīng)是最大值蹄溉,要讓整個組合更大,需更換nums[i-1]您炉。故交換nums[i-1]nums[j]柒爵。
  4. 逆序排列nums[i...n-1],使得該子序列最小赚爵,這保證了新的排列是所以比題目給定排列大的排列的最小排列棉胀。

但是我們需要注意一下幾點:

  1. 第1步中的條件必須是num[i-1] < nums[i]而不能相等,因為如果兩數(shù)相等冀膝,可能會導(dǎo)致求得的下一個排列不變唁奢。例如1, 1, 1, 5, 5的下一個排列本應(yīng)該是1, 1, 5, 1, 5,但如果有相等的條件窝剖,會導(dǎo)致nums[i-1] = nums[i] = 5麻掸。而在nums[i]右已沒有更多的數(shù),則求得的新排列不變赐纱。
  2. 第2步中的條件必須是nums[j] > nums[i-1]而不能相等脊奋。因為我們最終要交換nums[j]nums[i-1],若二者相等疙描,則交換后無法得到更大的排列狂魔。

代碼如下:

class Solution {
    public void nextPermutation(int[] nums) {
        int len = nums.length;
        int i = len-1;
        for (; i > 0; i--) {
            if (nums[i] >= nums[i-1]) break;
        }
        
        if (i == 0) {
            reverse(nums, 0, len-1);
            return;
        }
        int j = len-1;
        for (; j >= i; j--) {
            if (nums[j] > nums[i-1]) break;
        }
        swap(nums, i-1, j);
        reverse(nums, i, len-1);
    }
    
    public void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    
    public void reverse(int[] nums, int start, int end) {
        for(int i = start; i <= (start+end)/2; i++) {
            swap(nums, i, start+end-i);
        }
    }
}
  • 時間復(fù)雜度分析:
    最開始尋找nums[i]nums[i-1]的復(fù)雜度是O(n),尋找nums[j]的復(fù)雜度是O(n)淫痰,swap()函數(shù)的復(fù)雜度是O(1)最楷,最后reverse()函數(shù)的復(fù)雜度是O(n)。故最終的時間復(fù)雜度是O(n)待错。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末籽孙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子火俄,更是在濱河造成了極大的恐慌犯建,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓜客,死亡現(xiàn)場離奇詭異适瓦,居然都是意外死亡竿开,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門玻熙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來否彩,“玉大人,你說我怎么就攤上這事嗦随×欣螅” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵枚尼,是天一觀的道長贴浙。 經(jīng)常有香客問我,道長署恍,這世上最難降的妖魔是什么崎溃? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮盯质,結(jié)果婚禮上笨奠,老公的妹妹穿的比我還像新娘。我一直安慰自己唤殴,他們只是感情好般婆,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朵逝,像睡著了一般蔚袍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上配名,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天啤咽,我揣著相機(jī)與錄音,去河邊找鬼渠脉。 笑死宇整,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的芋膘。 我是一名探鬼主播鳞青,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼为朋!你這毒婦竟也來了臂拓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤习寸,失蹤者是張志新(化名)和其女友劉穎胶惰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霞溪,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡孵滞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年中捆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坊饶。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡泄伪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出幼东,到底是詐尸還是另有隱情臂容,我是刑警寧澤科雳,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布根蟹,位于F島的核電站,受9級特大地震影響糟秘,放射性物質(zhì)發(fā)生泄漏简逮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一尿赚、第九天 我趴在偏房一處隱蔽的房頂上張望散庶。 院中可真熱鬧,春花似錦凌净、人聲如沸悲龟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽须教。三九已至,卻和暖如春斩芭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工样眠, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留昼捍,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓琴庵,卻偏偏與公主長得像误算,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子迷殿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容