上一个排列和下一个排列
下一个排列:
思路:
1. 先找到需要改变的高位:从右向左扫描排列,若一直满足nums[i] > nums[i - 1],则说明这些元素是满足高位大于低位的,不需操作,直到找到nums[i] < nums[i - 1],找到高位比低位小的了,而且是“最低”的高位,这个位置就是我们需要做交换操作的。比如:6, 8, 7, 4, 3, 2 当中的8(发现6 < 8)
2. 第二步找要和这个高位交换的低位:原则是尽量寻找只比这个高位“大一点”的低位,因为只是下一个排列。因为在这个高位右边的数组满足从右往左递增,所以,我们重新从右边起扫描,找到第一个比这个高位大的元素。比如:6, 8, 7, 4, 3, 2 中的7.
3. 交换高位与低位,使得高位变大:比如6, 8, 7, 4, 3, 2 -> 7, 8, 6, 4, 3, 2
4. 此时,不论交换后的高位后面的元素是如何排列的,都肯定比之前的排列靠后了。因为只是下一个排列,所以我们现在尽量要现在的这个排列“靠前”,怎么做呢,就是按升序排列高位后面的元素,比如:按升序排列此时7后面的元素。因为此时高位后面的元素一定是从左往右,从大到小,所以,也相当于是翻转这一部分的数组。比如:7, 8, 6, 4, 3, 2 -> 7, 2, 3, 4, 6, 8
算法过程如下:
- 先从后往前找到 i 位置小于 i+1 位置的数,
- 从后往前找到第一个小于 i 位置 的数, 此数位置为 j
- 交换 i 和 j 。
- 逆序
上一个排列:
思路:
其实和下一个排列是一样的
1、上一个排列就是所有全排列按照升序排列后的上一个排列
2、如数字排列63624578,其上一个排列为63587642
3、由于是在所有升序排列中找到上一个排列,所以对于某一个排列,我们假设从某一位开始,后面的数字应当都是升序。
4、那我们从右到左找到第一个num[i]大于num[i+1]的位置。再从右到左找到第一个小于num[i]的位置将他们交换。
5、再将从i+1到nums.size()之间的数逆序,即前一个排列。
算法过程如下:
- 先从后往前找到 i 位置大于 i+1 位置的数,
- 从后往前找到第一个大于 i 位置 的数, 此数位置为 j
- 交换 i 和 j 。
- 逆序
#include<iostream> #include<vector> #include<algorithm> using namespace std; vector<int> nextPermuation(vector<int>& nums) { int len = nums.size(); if (len == 0) return nums; int pos = -1; for (int i = len - 2; i >= 0; i--) { if (nums[i] < nums[i + 1]) { pos = i; break; } } if (pos == -1) { reverse(nums.begin(), nums.end()); return nums; } else { for (int i = len - 1; i > pos; i--) { if (nums[pos] < nums[i]) { swap(nums[pos], nums[i]); reverse(nums.begin() + pos + 1, nums.end()); break; } } } return nums; } vector<int> previousPermuation(vector<int>& nums) { int len = nums.size(); if (len <= 0) return nums; int pos = -1; for (int i = len - 2; i >= 0; i--) { if (nums[i] > nums[i + 1]) { pos = i; break; } } if (pos == -1) { reverse(nums.begin(), nums.end()); return nums; } else { for (int i = len - 1; i > pos; i--) { if (nums[pos] > nums[i]) { swap(nums[pos], nums[i]); reverse(nums.begin() + pos + 1 , nums.end()); break; } } } return nums; } int main() { vector<int> nums = { 2,4,3,5 }; vector<int> res1,res2; res1 = previousPermuation(nums); vector<int> nums2 = { 2,3,4,5 }; res2 = nextPermuation(nums); for (auto i : res1) cout << i << " "; cout << endl; for (auto i : res2) cout << i << " "; cout << endl; system("pause"); return 0; }