leetcode:next-permutation

实现下一个排列,它将数字重新排列到字典上的下一个更大的数字排列。
如果这种安排不可能,则必须将其重新排列为尽可能低的顺序(即按升序排序)。
替换必须就地,不要分配额外的内存。

输入位于左侧列中,其相应的输出位于右侧列中。
1, 2, 3 → 1, 3, 2
3, 2, 1 → 1, 2, 3
1, 1, 5 → 1, 5, 1

解题思路:

  1. 这道题分两种情况
  2. 第一种情况,当前排列已经是最大的排列了,这时只需要将当前的排列 reverse 即可
  3. 第二种情况,当前排列只是中间的一个不大不小的排列,那么就需要定位到需要交换数字的位置,交换之后,还需要将交换后的后半部分数组进行 reverse
  4. 拿 2,5,4,3 为例,从后向前遍历,如果是递增的顺序,那么跳过,找到了 2 和 5 不是递增的关系,锁定了 2,i 表示 2 的位置,然后再从前往后找,找到仅大于 2 的数 3,用 j 表示 3 的位置,交换 2 和 3
  5. 这时原数列变成了 3,5,4,2,但是这个数不是 2,5,4,3 的下一个排列, 需要后面的数进行 reverse,reverse 5,4,2 之后,就变成了 3,2,4,5, 就是正确答案了

代码如下:

public void nextPermutation(int[] num) {
	// 考虑到边界情况,需要进行处理
        if(num == null || num.length < 2) return;

	// 锁定 i 的位置
        int i =  num.length - 1;
        while(i > 0 && num[i] <= num[i - 1])
            i--;

	// 如果数列不是升序排列,锁定 j 的位置
        if(i > 0){
            int j = i ;
            while(j < num.length && num[j] > num[i - 1]) j++;
            j--;
	    
		// 交换 i 和 j 的位置上的数
            swap(num,i - 1,j);
        }
		
	// 对余下的数进行全排列
        reverse(num,i , num.length - 1);
    }

    public void swap(int[] num,int i,int j){
        int temp = num[i];
        num[i] = num[j];
        num[j] = temp;
    }

    public void reverse(int[] num, int i, int j){
        while(i < j){
            swap(num, i++, j--);
        }
    }

转载于:https://my.oschina.net/happywe/blog/3072776

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值