问题链接
题目解析
求序列的下一个字典序列。
解题思路
什么是下一个字典序列?了解一下:next_permutation(全排列算法)。算法的核心思想:
- 从序列尾部开始往前寻找两个相邻元素,设为(i,ii),即有 \(\*i < \*ii\)。
- 再次从序列尾部往前寻找第一个大于 i 的元素,设为 j,即有 \(\*j > \*i\)。交换(*i,*j)。
- 将从 *ii 开始在尾部的所有元素逆序排列。
//注:第二第三步可交换,即先全部逆序,再找两个交换也OK,不过在找 *j 时需要正序从 *i++ 开始找。
本题的目的应该是要实现该算法,看过描述后可以直接写出代码。
一行代码
class Solution {
public:
void nextPermutation(vector<int>& nums) {
next_permutation(nums.begin(), nums.end());
}
};
如果只是这样的话,那就没什么意思了:)
具体实现
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int i, j, n = nums.size();
for(i = n - 2; i >= 0; i--) {
if (nums[i + 1] > nums[i]) {
for(j = n - 1; j > i; j--) {
if (nums[j] > nums[i]) break;
}
swap(nums[i], nums[j]);
reverse(nums.begin() + i + 1, nums.end());
return;
}
}
reverse(nums.begin(), nums.end());//全部逆序排列
}
};
当然,想要具体再把swap和revese函数实现也可以,可参考Next Permutation。我认为重点理解如何求解下一个序列的方法就OK,没有必要太过深入。另外,上述代码可以稍微简化一下,道理是一样的,代码如下:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n = nums.size(), i = n-2, j = n-1;
while(i >= 0 && nums[i] >= nums[i+1]) i--;
if(i >= 0) {
while(nums[i] >= nums[j]) j--;
swap(nums[i], nums[j]);
}
reverse(nums.begin()+i+1, nums.end());
}
};
相似题目
LeetCode All in One题解汇总(持续更新中...)
本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.