leetcode31. 下一个全排列
leetcode31. next permutation
这道题可以先从极端情况入手考虑:
-
第一个全排列:
1 2 3 4 5
,完全升序的 -
最后一个全排列:
5 4 3 2 1
,完全降序的
有一个很显然的结论:为了最小化我们的操作对字典序的影响,我们要尽量修改靠后的元素的顺序。
所以,我们能确定,我们需要从后向前扫描,寻找需要交换的元素。
而我们也已经确定,如果一段序列是单调下降的,那么它的字典序就没有增大的余地,所以我们可以得到这样的做法:
从后向前扫描,跳过单调递增的部分(对应正序的单调下降),在第一个转折点处,记录当前的元素,然后找到后面最小的、比这个点大的元素,对他们进行交换,然后对整个序列靠后的部分进行逆序,可以通过图片很直观地理解:
由于交换后,最后的一堆元素是倒序的,字典序是新顺序当中最大的,我们reverse一遍,就能变成最小的了。
代码:
# include <iostream>
# include <array>
# include <algorithm>
# include <vector>
class Solution {
public:
void nextPermutation(std::vector<int>& nums) {
int i = nums.size() - 2;
while(i >= 0 && nums[i] >= nums[i + 1])
i--;
if (i < 0) {
std::reverse(nums.begin(), nums.end());
return;
}
int j = nums.size() - 1;
while(j >= 0 && nums[j] <= nums[i])
j--;
std::swap(nums[i], nums[j]);
std::reverse(nums.begin() + i + 1, nums.end());
}
};
int main() {
Solution s;
std::vector<int> nums{1,1,5};
s.nextPermutation(nums);
for(auto x: nums) {
std::cout << x << " ";
}
std::cout << std::endl;
}
本文作者:Gold_stein
本文链接:https://www.cnblogs.com/smartljy/p/18611098
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步