Description
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place and use only constant extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
Examples
Example1
input: [1, 2, 3]
output: [1, 3, 2]
Example2
input: [3, 2, 1]
output: [1, 2, 3]
解题思路
先梳理一下题目,其实英文的没太看懂……去翻了下leetcode中国看了中文的题目,想表达的意思就是
给你一串数,这串数是有顺序的,且越靠前所占比重越大
- 如果这串数按照现有的排列所组成的数串是最大的,那么就将顺序颠倒(即重新排序使其变成最小的)
- 如果现有排序不是最大的,那么就将其变成仅仅比当前排序大的下一个数串
我们假设输入的数都是个位数,那就可以简单的将其理解成十进制数了,比如输入[1, 2, 3, 4, 5],就相当于12345,由于这五个数可以组成的最大值为54321,明显不符合12345,所以我们就找一个仅比12345大一轮的数串[1, 2, 3, 5, 4],那最后的输出就是12354啦
那目标就是找到12354
其实经过一些规律推测,可以得到以下结论:
- 需要被交换的数一定满足 nums[i]<nums[i+1]nums[i] < nums[i + 1]nums[i]<nums[i+1]
- 并不是相邻左右交换,而是在该数右侧从右往左进行观察,选择第一个比他大的数进行交换,这样可以确保:
1)由于被交换的数右侧一定满足nums[i]<nums[i+1]nums[i] < nums[i + 1]nums[i]<nums[i+1],所以其右侧一定是非递增序列
2)这样可以确保交换过去之后右侧仍旧是非递增序列
3)而且可以确保被交换过来的是比被交换数大的里面最小的那个(确保下一个更大数) - 然后对右侧的所有数进行逆序操作,依旧是为了确保满足下一个更大数
举个例子
- 1 9 8 8 7 6
- 到1的时候发现1比9大了
- 所以倒回去从右往左找比1大的数
- 发现是6
- 1和6进行交换
- 6 9 8 8 7 1
- 然后将右侧进行逆序
- 6 1 7 8 8 9
- OK啦~
其实代码里面 i == -1 的情况不用单分出来但是懒得改了欸嘿
class Solution {
public void nextPermutation(int[] nums) {
int i, j, k;
for(i = nums.length - 2; i >= 0; i--){
if(nums[i] < nums[i + 1])
break;
}
if(i == -1)
Arrays.sort(nums);
else{
int comp = nums[i];
for(j = nums.length - 1; j > i; j--){
if(comp < nums[j])
break;
}
int temp;
int length = nums.length;
temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
i++;
for(j = 0; j < (length - i) / 2; j++){
temp = nums[j + i];
nums[j + i] = nums[length - 1 - j];
nums[length - 1 - j] = temp;
}
}
}
}
其他
- 这题主要是规律寻找吧
- 刚开始没有找到这么多规律还想着冒泡来着hhhhh
- 后来一直卡bug一直卡bug就逐渐找到了这么多规律……
- Hmmmmmm最后bug出在交换的时候第一个 numnumnum 写了 num[j+i]num[j + i]num[j+i] 第二个 numnumnum 写了 num[j]num[j]num[j] 没写 [j+i][j + i][j+i] ……
- 最后的最后,尝试了CCF还是喜欢leetcode简洁明了的命题方式