问题描述
给出一个数组,要求找出比这个数组组成的数字大的最小的那个数字组合,如果没有找到,则输出这个数组组成的数字的最小值的组合。题目链接:**点我**
样例输入输出
由于函数没有返回值,是直接更改的输入的数组,因此此处的输出指更改后的数组的值
输入:[1,1,2]
输出:[1,2,1]
输入:[3,2,1]
输出:[1,2,3]
问题解法
此解法主要参考leetcode上文章的解法,详细参考点击**这里**
主要过程如下:
- 先从数组右边向左边查找,找到右边数字比左边数字大的值,记录此时较小的值,如果没找到,则逆序整个数组,结束。
- 从数组右边向左边查找,找出第一个比上一步中找到的值大的值,交换这两个值。此时第一步中记录的值后面的值呈降序排列的状态(后面证明)。
- 将第一步找到的值后面的降序排列的值逆序,使其呈升序排列,此时得到结果。
其过程大致如下图所示:
说明:此图片来自https://leetcode.com/articles/next-permutation
现在证明在交换两个数之后,后面的数字是降序排列的。由于交换前,后面片段的是降序排列的,所以只需要证明交换后前后三个数是降序的即可。假设要将 a[i]
和 a[j]
进行交换,则必有以下不等式成立
1 2
| a[j + 1] < a[i] < a[j] a[j + 1] < a[j] < a[j - 1]
|
现在要证明交换后 a[j + 1] <= a[i] <= a[j - 1]
。用反证法进行证明。
先证明 a[j + 1] <= a[i]
。
1 2 3
| 假设 a[j + 1] > a[i] 与已知 a[j + 1] < a[i] 矛盾 故 a[j + 1] <= a[i] 成立
|
现在证明a[i] <= a[j - 1]
1 2 3 4
| 假设 a[i] > a[j - 1] 由于 a[j + 1] < a[j] < a[j - 1] 所以 a[i] > a[j - 1] > a[j],与已知 a[i] < a[j]矛盾 故 a[i] <= a[j - 1] 成立
|
综上所述,在交换值后,后面的值仍然维持者降序的顺序。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| class Solution { private int findLessIndex(int[] nums) { for (int i = nums.length - 1; i >= 1; i--) { if (nums[i] > nums[i - 1]) { return i - 1; } } return -1; } private int findSwapIndex(int[] nums, int index) { for (int i = nums.length - 1; i > index; i--) { if (nums[i] > nums[index]) { return i; } } return -1; } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } private void reverse(int[] nums, int startIndex, int endIndex) { int endRange = (endIndex - startIndex + 1) / 2; for (int i = 0; i < endRange; i++) { swap(nums, startIndex + i, endIndex - i); } } public void nextPermutation(int[] nums) { int lessIndex = findLessIndex(nums); if (lessIndex == -1) { reverse(nums, 0, nums.length - 1); return; } int swapIndex = findSwapIndex(nums, lessIndex); if (swapIndex == -1) { reverse(nums, lessIndex + 1, nums.length - 1); return; } swap(nums, lessIndex, swapIndex); reverse(nums, lessIndex + 1, nums.length - 1); } }
|
参考来源
https://leetcode.com/articles/next-permutation/