一,题目描述:
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,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做一个递增。
三,C++代码:
class Solution {
public:
void nextPermutation(vector<int> &num) {
int index = num.size() - 1;
while (num[index - 1] >= num[index]){ // 逆序则继续
index--;
}
if (index == 0){ // 整个数组都是逆序的
sort(num.begin(), num.end());
return;
}
// 找到第一个大于,此时4的索引是index-1
for (int i = num.size() - 1; i >= index; i--){
if (num[i] > num[index - 1]){
swap(num[i], num[index - 1]);
break;
}
}
sort(num.begin() + index, num.end()); // 再将后面的数从小到大排序
return;
}
};