標籤:permutatio leecode 排列 排序 vector
翻譯
實現“下一個排列”函數,將排列中的數字重新排列成字典序中的下一個更大的排列。如果這樣的重新排列是不可能的,它必須重新排列為可能的最低順序(即升序排序)。重排必須在原地,不分配額外的記憶體。以下是一些樣本,左側是輸入,右側是輸出:1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1
原文
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,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1
題意
哎,我那捉急的英語水平讓我都看不懂題目,只能去翻Google翻譯了……
什麼字典序,又不是字母……排列?什麼鬼……
後來才發現原來是數學中的排列組合,比如“1,2,3”的全排列,依次是:
1 2 31 3 22 1 32 3 13 1 23 2 1
所以題目的意思是,從上面的某一行重排到期下一行,如果已經是最後一行了,則重排成第一行。
但是也不能根據給出的數組中的數字列出所有排列,因為要求不能佔用額外的空間。
分析
網上看來一個樣本,覺得挺好的,也沒必要另外找一個了。
6 5 4 8 7 5 1
一開始沒看對方的後面介紹,就自己在想這個排列的下一個排列是怎樣的。
首先肯定從後面開始看,1和5調換了沒有用。7、5和1調換了也沒有效果,因此而發現了8、7、5、1是遞減的。如果想要找到下一個排列,找到遞增的位置是關鍵。因為在這裡才可以使其增長得更大。於是找到了4,顯而易見4過了是5而不是8或者7更不是1。因此就需要找出比4大但在這些大數裡面最小的值,並將其兩者調換。那麼整個排列就成了:6 5 5 8 7 4 1然而最後一步將後面的8 7 4 1做一個遞增。
代碼
根據上面的思路,在記事本上一氣呵成寫了如下代碼:
class Solution {public: void nextPermutation(vector<int>& nums) { int index = nums.size() - 1; while(nums[index] < nums[index-1]) { --index; } if(index == 0) { sort(nums.begin(), nums.end()); return ; } int second = INT_MAX, secondIndex = INT_MAX; for(int i = nums.size() - 1; i >= index - 1; -- i) { if(nums[i] > nums[index - 1]) { if(nums[i] < second) { second = nums[i]; secondIndex = i; } } } int temp = nums[index - 1]; nums[index - 1] = nums[secondIndex]; nums[secondIndex] = temp; sort(nums.begin()+index, nums.end()); }}
提交到LeetCode上,發現錯了……最後一行少了一個分號,加上之後還是錯了……
沒辦法還是老老實實寫到CodeBlocks上調試,加上一個符號就對了(下面的 = ):
while(nums[index] <= nums[index-1]) { --index;}
於是接下來再看看別人的解法,有如下3個區別:
while(index > 0){ if(num[index] > num[index - 1]){ break; } index--;}
int exchangeIndex;for(int i = num.size()-1; i >= index; i--){ if(num[i] > num[index-1]){ exchangeIndex = i; break; }}
swap(num[index-1],num[exchangeIndex]);
while迴圈這一部分我的更簡單,不過其他的就要複雜些了,swap都沒想到……
擴充
在C++標準庫中還有一個函數next_permutation,其正是用於求一個數字序列的下一個排序。
void nextPermutation(vector<int> &num) { next_permutation( num.begin(), num.end() ); }
再接再厲……
著作權聲明:本文為 NoMasp柯於旺 原創文章,未經許可嚴禁轉載!歡迎訪問我的部落格:http://blog.csdn.net/nomasp
LeetCode 31 Next Permutation(下一個排列)