【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 };
相关文章
相关标签/搜索