1

题目详情

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.

题目的意思是找到当前元素排列的‘下一个排列’。那么什么叫‘下一个排列呢’?这里举个例子,比如说元素1,2,3。它们的全排列是‘1,2,3’,‘1,3,2’,‘2,1,3’,‘2,3,1’,‘3,1,2’,‘3,2,1’因此比如求‘123’的下一个排列,就应该返回‘1,3,2’.
如果当前的序列不存在‘下一个排列’,那么就返回完全升序的第一个排列。

例子: 左侧一列是输入,右侧是正确的输出:
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

想法

  • 当我们要求一个排列的‘下一个排列’,我们需要意识到问题的关键在于从数组末端遍历到的,第一个不满足nums[i] <= nums[i+1]条件的元素。
  • 我们所找到的这个元素就是排序需要改变的第一个元素。
  • 然后我们选取一个刚好大于此元素的数,与当前元素进行替换。并对后面的所有元素重新按照升序排列就可以得到最终的答案。
  • 我描述的不是很清晰,这里引用一张leetcode上的图讲解

31_Next_Permutation.gif

解法

    public void nextPermutation(int[] nums) {
        int length = nums.length;
        int i= length-2;
        while(i>=0 && nums[i+1] <= nums[i])i--;
        if(i >= 0){
            int j = length -1;
            while(j >= 0 && nums[j] <= nums[i])j--;
            swap(nums,i,j);
        }
        reverse(nums,i+1);
    }
    
    public void reverse(int[] nums,int start){
        int end = nums.length-1;
        while(start < end){
            swap(nums,start,end);
            start ++;
            end --;
        }
    }
    
    public void swap(int[] nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

soleil阿璐
350 声望45 粉丝

stay real ~