File tree Expand file tree Collapse file tree 2 files changed +48
-0
lines changed Expand file tree Collapse file tree 2 files changed +48
-0
lines changed Original file line number Diff line number Diff line change 10
10
20. 有效的括号
11
11
21. 合并两个有序链表
12
12
22. 括号生成
13
+ 31. 下一个排列
13
14
37. 解数独
14
15
39. 组合总和
15
16
40. 组合总和 II
Original file line number Diff line number Diff line change
1
+ // 31. 下一个排列
2
+
3
+
4
+ /*
5
+ 1、“下一个排列”定义:
6
+ 1)给定数字序列的字典序中下一个更大的排列。可以理解成这些数字拼凑成的多个整数,升序排序,然后求当前整数的下一个整数
7
+ 2)如果不存在下一个更大的排列,则将数字重新排列成最小的排列。即整数是最大的,那么整体升序排列得到一个最小的整数
8
+ 2、算法推导
9
+ 1)我们希望下一个数比当前数大,这样才满足“下一个排列”的定义。因此只需要将后面的「大数」与前面的「小数」交换,就能得到一个更大的数
10
+ 2)我们还希望下一个数增加的幅度尽可能的小,这样才满足“下一个排列与当前排列紧邻“的要求。为了满足这个要求,需要:
11
+ ① 在尽可能靠右的低位进行交换,需要从后向前查找
12
+ ② 将一个尽可能小的「大数」与前面的「小数」交换
13
+ ③ 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列
14
+ 3、算法过程
15
+ 1)从后向前查找第一个相邻升序的元素对 (i-1,i),满足 A[i-1] < A[i],即找到第一个可交换的最低位「小数」。此时 [i,end) 必然是降序
16
+ 2)在 [i,end) 从后向前查找第一个满足 A[i-1] < A[j] 的 j,即找到第一个可交换的值最小的「大数」。A[i-1]、A[j] 分别是「小数」、「大数」
17
+ 3)将 A[i-1] 与 A[j] 交换
18
+ 4)此时 [i,end) 必然是降序,逆置 [i,end),使其升序
19
+ 5)如果在步骤1找不到符合的相邻升序元素对,说明当前 [0,end) 为一个降序顺序,即最大的排序,则整体升序得到最小的排列
20
+
21
+ 1 2 3 8 5 7 6 4
22
+ ↑ ↑ ↑
23
+ i-1 i j
24
+ 1 2 3 8 6 4 5 7
25
+ */
26
+ class Solution {
27
+ public void nextPermutation (int [] nums ) {
28
+ int n = nums .length ;
29
+ if (n <= 1 ) {
30
+ return ;
31
+ }
32
+ for (int i = n - 1 ; i >= 1 ; i --) {
33
+ if (nums [i ] > nums [i - 1 ]) {
34
+ for (int j = n - 1 ; j >= i ; j --) {
35
+ if (nums [j ] > nums [i - 1 ]) {
36
+ int temp = nums [j ];
37
+ nums [j ] = nums [i - 1 ];
38
+ nums [i - 1 ] = temp ;
39
+ Arrays .sort (nums , i , n );
40
+ return ;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ Arrays .sort (nums );
46
+ }
47
+ }
You can’t perform that action at this time.
0 commit comments