[LeetCode] 31. 下一个排列(java实现)找规律
1. 题目
2. 读题(需要重点注意的东西)
思路(找规律):
反过来找到第一个非降序的位置(反过来找的目的是尽可能保证高位不变,变低位,从而能得到最小的排列),将后面的比当前位置大的最小的数换过来,然后将后面的所有数按从小到大排序即可。
举一个例子:
例有如下序列 2 3 5 4 1
第一个非降序的位置在 2 和 3 之处,找剩余的数中比 3 大的最小的数,为4,交换这两个数,得到2 4
5 3
1
然后将原放3后的所有数按从小到大排列 得到 2 4 1 3 5 ,即为nums的下一个排列。
3. 解法
---------------------------------------------------解法---------------------------------------------------:
class Solution {
public static void swap(int[] nums,int a,int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
public static void reverse(int[] nums,int l,int r){
while(l < r) swap(nums,l++,r--);
}
public void nextPermutation(int[] nums) {
int n = nums.length - 1;
int k = n;
// 反过来找升序的数
// 如果序列是降序,则k--
while(k > 0 && nums[k - 1] >= nums[k]) k--;
// 如果整个序列都是降序 说明已经是最大的排序,直接翻转
if(k <= 0) reverse(nums,0,n);
// 找到一个升序 如 2 3(k-1) 5(k) 4 1 中的 3
else{
// 找比k-1大的最小的数t-1
int t = k;
while(t <= n && nums[t] > nums[k - 1]) t++;
// 找到这个数的位置为t - 1,交换t - 1和k - 1
// 如 2 3(k-1) 5(k) 4(t-1) 1(t) (n)
swap(nums,t - 1,k - 1); // 2 4 5 3 1
// 将后面的数k ~ n变为升序
reverse(nums,k,n);
}
}
}
可能存在的问题:
4. 可能有帮助的前置习题
5. 所用到的数据结构与算法思想
6. 总结
最主要的是弄清楚各个下标,交换的是哪个下标的值,逆转的是哪个下标中的元素