【leetcode】Next Permutation

Next Permutation

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).spa

The replacement must be in-place, do not allocate extra memory.code

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,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1blog

 
 
先從後往前尋找,找到首次降低的位置i      (找到進位的位置)
從位置i開始,日後尋找,找到第一個小於等於num[i]的位置j,  交換i和j-1(找到進位後,最高位的值)
將i+1後面的元素逆序排列 (取最小)
 
用一個例子來講明,好比排列是(2,3,6,5,4,1),求下一個排列的基本步驟是這樣:
1) 先從後往前找到第一個不是依次增加的數,記錄下位置p。好比例子中的3,對應的位置是1;
2) 接下來分兩種狀況:
    (1) 若是上面的數字都是依次增加的,那麼說明這是最後一個排列,下一個就是第一個,其實把全部數字反轉過來便可(好比(6,5,4,3,2,1)下一個是(1,2,3,4,5,6));
    (2) 不然,若是p存在,從p開始日後找,找到下一個數就比p對應的數小的數字,而後兩個調換位置,好比例子中的4。調換位置後獲得(2,4,6,5,3,1)。最後把p以後的全部數字倒序,好比例子中獲得(2,4,1,3,5,6), 這個便是要求的下一個排列。

以上方法中,最壞狀況須要掃描數組三次,因此時間複雜度是O(3*n)=O(n),空間複雜度是O(1)。代碼以下:it

 
 1 class Solution {
 2 public:
 3     void nextPermutation(vector<int> &num) {
 4        
 5         int n=num.size();
 6         int i,j;
 7         for(i=n-2;i>=0;i--)
 8         {
 9             if(num[i]<num[i+1])
10             {
11                 break;
12             }
13         }
14         if(i>=0)
15         {
16             for(j=i+1;j<n;j++)
17             {
18                 if(num[j]<=num[i])
19                 {
20                     break;
21                 }
22             }
23             j--;
24             swap(num[i],num[j]);
25         }
26        
27         reverse(num.begin()+i+1,num.end());
28     }
29    
30    
31     void swap(int &a,int &b)
32     {
33         int tmp=a;
34         a=b;
35         b=tmp;
36     }
37 };
相關文章
相關標籤/搜索