1053. Previous Permutation With One Swap-medium-leetcode

我可以发现,从后往前,如果是降序的,我们无论怎么代替都不会比现在小,因为降序本身就是最小的。如果不是降序,那么我们就要找到第一个不是降序的数字,也就是我们准备交换的数字,之后我们在该数字身后的数(一定是从右往左,越来越小)中找到第一个比他小的数字,与之交换,则得到最终答案(要处理相同数字的情况),如果后面降序中存在相同,那么我们选最靠前的那个数字来交换。

class Solution {
    public int[] prevPermOpt1(int[] A) {
        int l = A.length-2;
        while(l>=0 && A[l]<=A[l+1]){
            l--;
        }
        if(l<0) return A;
        int r = A.length-1;
        while(A[r]>=A[l]){
            r--;
        }
        while(A[r]==A[r-1]){
            r--;
        }
        int tmp = A[l];
        A[l] = A[r];
        A[r] = tmp;
        return A;
    }
}

这个问题其实和按照字典序来寻找当前数的下一个数这一问题是类似的。如果当前数从右到左是升序的,那说明当前数就是最大的。那它下一个数就是最小的数(形成个循环),其实就是不需要任何操作了。从右到左,找到第一个形成降序的位置,记为i。然后再从右到左,找到第一个比i位置大的数。交换i,j位置的数。然后将i位置之后的数从小到大排序。
这道题本身其实就是字典序问题,只不过不需要调整顺序那一步了,直接交换位置就完事了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值