下一个排列
下一个排列
https://leetcode-cn.com/problems/next-permutation/
交换 + 反转
容易看出,下一个排列的数字在数学上一定会比前一个排列大。因此,我们希望:
- 下一个数比当前数大,且是一个排列
- 可以通过将一个靠后的「大数」和一个靠前的「小数」交换来得到
- 下一个数增加的幅度尽可能小
+「小数」尽可能地靠右:比如123465
,下一个排列应该把 5 和 4 交换而不是把 5 和 1 交换- 「大数」尽可能地小:比如
123465
,下一个排列应该把 5 和 4 交换而不是把 6 和 4 交换 - 交换后,需要将「大数」后面的数重排为升序,这样这个排列才就是交换后最小的
- 「大数」尽可能地小:比如
算法步骤:
- 从后向前查找第一个相邻升序的元素对 (i,j),满足 A[i] < A[j]。此时 [j,end) 必然是降序
- 在 [j,end) 从后向前查找第一个满足 A[i] < A[k] 的 k。A[i]、A[k] 分别就是上文所说的「小数」、「大数」
- 将 A[i] 与 A[k] 交换
- 可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序
- 如果在步骤 1 找不到符合的相邻元素对,说明当前 [begin,end) 为一个降序顺序,则直接跳到步骤 4
1 |
|