题目:
整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。
例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。必须 原地 修改,只允许使用额外常数空间。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/next-permutation
思路:
字典数:本题中将数组中的数字组合成数字,按照递增的顺序排列;
步骤:找尽量靠右的较小数字(位数原因);尽量小的较大数字,二者交换;交换后,较大数字后的全部升序排列!
找到下一个字典数:
①从后往前找到第一个递增对;(如果全是递减,说明已经是最大的,直接全部逆序就可以)
②从较小数字后的数字中找到一个比它大的数字(范围内尽量小);此时较小数字后范围内的数字是严格递减的,因此从后往前找就好!
③二者交换后,后面区间中的数字升序排列;此时后面区间中的数字也是严格递减的!
代码:
1)遍历交换
class Solution {
public void nextPermutation(int[] nums) {
int i = nums.length - 2;
//从后往前找第一个递增对;尽量保证了位数的较低位
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
//如果i<0,说明全是递减的,已经是最大的字典数了,之间逆序成最小的即可
if (i >= 0) {
int j = nums.length - 1;
//从后往前找到第一个比i处大的数值,进行交换
while (j > i && nums[i] >= nums[j]) {
j--;
}
swap(nums, i, j);
}
//从交换后的位置处,升序排列;
//交换之后,后面的那部分也是严格降序排列!
reverse(nums, i + 1);
}
//交换方法
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
//升序排列方法
public void reverse(int[] nums, int start) {
int i = start;
int j = nums.length - 1;
//条件为i < j;奇数偶数都可以
while(i < j){
swap(nums,i,j);
i++;
j--;
}
}
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/next-permutation/solution/xia-yi-ge-pai-lie-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。