题目
计算字典序排列的下一个排列,原地算法。
例如 1,2,3
的字典序排列如下。
1 | 1 2 3 |
分析
对于 123 做分析发现:
- 当所有值递减(或相等)时,也就组成了最大值,下一个排列为全部翻转得到的最小值。
- 当最后两位递增时,下一个排列只需要交换最后两位即可,例如
1 2 3 --> 1 3 2
。 - 当最后两位递减(或相等)时,不能交换最后两位,而需要让倒数第三位增大,也就是从后面找一个刚好更大一点的数据填上去,为了原地操作,直接交换位置。例如
1 3 2 --> 2 3 1
。
上面第三种情况比较复杂,再找个复杂的例子:
1 | 5 2 4 3 1 |
考虑到数组中可能有重复元素,再找一个例子:
1 | 8 2 4 3 3‘ 2’ 2“ 1 |
所以完整的逻辑是:
- 如果整个数组都是递减的,说明是最大值,下一个排列应该是最小值,全部翻转即可。
- 找到末尾最长的递减序列,其起始index记为
k
,满足:[k-1] < [k] >= [k+1] >= .. >= [n-1]
。
- 从最末尾开始,找到第一个刚好大于
[k-1]
的数字[x]
,因为[k] > [k-1]
,这个数字肯定是存在的。 - 交换
[k-1]
和[x]
,然后翻转[k] ~ [n-1]
。
代码:
1 | class Solution { |