题目:下一个排列
思路:找规律。在字典序中,用在字典中出现的次序代表该字符的值,用直接连接字符,那么最小排列的字符串就是单调递增的一条直线。从最小排列开始逐渐增大排列,那么可以发现从直线的末端开始,会不断的出现顶点并向前延伸,直到直线变成了单调递减。可以发现每一次增大的排列都是末端顶点向前移动。为了更好的说明情况,这边引用题解中的一张图。
- 从尾端向前搜索,直到到达第一个顶点处;(从4向1方向搜索,7这个位置为搜索到的第一个顶点)
- 那么顶点的前一个字符,就是我们需要被替换的字符,替换的字符是在刚刚搜索中比被替换字符大一点的字符;(5是被替换的字符,7和6都比5大,选其中最小的作为替换字符,这儿选6是替换字符)
- 替换完后对从顶点位置开始进行升序排列。(替换后的排列是12386754,从顶点7开始排序,即
754
->457
) - 上述步骤完成后,就得到下一个排列。(
12385764
->12386457
)
代码:
class Solution {
public void nextPermutation(int[] nums) {
int idx = nums.length-1;
while(idx > 0 && nums[idx] <= nums[idx-1]) --idx;
if(idx <= 0) {
reverse(nums);
}else{
int i = idx;
while(i<nums.length && nums[i] > nums[idx-1]) i++;
int t = nums[idx-1] ^ nums[i-1];
nums[idx-1] ^= t;
nums[i-1] ^= t;
Arrays.sort(nums, idx, nums.length);
}
}
private void reverse(int[] nums){
for(int l = 0, r = nums.length - 1, t = 0; l < r; l++, r--){
t = nums[l] ^ nums[r];
nums[l] ^= t;
nums[r] ^= t;
}
}
}
执行用时:1 ms, 在所有 Java 提交中击败了96.93%的用户
内存消耗:38.5 MB, 在所有 Java 提交中击败了79.92%的用户