Skip to content

Instantly share code, notes, and snippets.

@HaiyangXu
Created May 10, 2014 13:03
Show Gist options
  • Save HaiyangXu/e79e6f3cdb349fb7111e to your computer and use it in GitHub Desktop.
Save HaiyangXu/e79e6f3cdb349fb7111e to your computer and use it in GitHub Desktop.
class Solution {
public:
void nextPermutation(vector<int> &num) {
for(int i=num.size()-1;i-1>=0;--i)
{
if(num[i]>num[i-1])//找到最大的降序后缀 1[2]876530
{
for(int j=num.size()-1;j>=i;--j)
{
if(num[j]>num[i-1]) //在降序后缀中找到第一个大于前缀的数 1[2]8765[3]0
{
swap(num[j],num[i-1]);//交换 1[3]8765[2]0
reverse(num.begin()+i,num.end()); //对后缀逆序 13025678
return ;
}
}
}
}
reverse(num.begin(),num.end()); //若已为最大排列,返回最小排列
}
};
@HaiyangXu
Copy link
Author

为了得到下一个排列,要尽可能小的增长这个序列。
例如对于 01 的下一个排列,我们应该对最右边的1进行加一得到 02,而不会对左边的0进行加1得到11.也就是说我们应该对右边的低位序列进行增长,这样才能保证最小的增长。

  • 首先就要找到右边最长的非递减子序列,如下图5330 ,这个后缀已经是最大的序列了我们无法对他进行增长,所以要对这个最长的非递减序列的左边的一个数2上进行增长。

  • 要保证最小增长,那么我们要从后缀5330中找到最小的那个大于2的数和2进行交换

  • 交换过后我们要保证后缀最小,才能保证最小增长,而后缀已经是非递减的了,所以逆序即可

    参考ref

enter image description here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment