leetcode算法题--使序列递增的最小交换次数★

本文详细解析了一道 LeetCode 上的题目“Minimum Swaps to Make Sequences Increasing”,通过动态规划的方法来解决。文章中介绍了 dp 数组的概念,其中 dp[0] 表示当前位置不做交换时的最小交换次数,dp[1] 表示做交换时的最小交换次数。通过四种状态的分析,结合贪心策略,实现了对序列的优化,最终返回最小的交换次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题链接:https://leetcode-cn.com/problems/minimum-swaps-to-make-sequences-increasing/

动态规划

dp[0]表示若当前位置不做交换时的次数
dp[1]表示若当前位置做交换时的次数

同时初始化dp[0]=0,dp[1]=1,表示第一步要么换要么不换。然后分析一下题目的状态,共有四种状态:

1、A[i-1]<A[i] && B[i-1]< B[i] 
2、A[i-1]>=A[i] || B[i-1]>=B[i]
3、A[i-1]>=B[i] || B[i-1]>=A[i]
4、A[i-1]<B[i] && B[i-1]<A[i]

然后对每个状态考虑如何状态转移,backup保存dp上个位置的状态。

1、 正确的情况,不一定做改变,如果前一个交换了,这个可以交换或不交换;如果前一个不交换,这个也可以交换或不交换。
dp[0]=backup[0]||backup[1];
dp[1]=backup[0]+1||backup[1]+1;
2、 必须做改变,如果前一个交换了,则这个不用交换;如果前一个没交换,则这个交换。
dp[0]=backup[1];
dp[1]=backup[0]+1;
3、 不一定做改变,但是如果前一个交换了,这个也必须交换;如果前一个没有交换,则这个也不用交换。
dp[0]=backup[0];
dp[1]=backup[1]+1;
4、不一定做改变,如果前一个交换了,这个可以交换或不交换;如果前一个不交换,这个也可以交换或不交换,同1的情形是一样的。
dp[0]=backup[0]||backup[1];
dp[1]=backup[0]+1||backup[1]+1;

值得注意的是,2和3是互斥的,同时只有一个可能发生;而1和4不是互斥的,可能同时发生,所以将两种情况整合在一起,用贪心算法,既然可做可不做,那就不做,取前一步的最小值min(backup[0],backup[1]),于是dp[0]=min,dp[1]=min+1。

int minSwap(vector<int>& A, vector<int>& B) {
    int len=A.size();
    vector<int> dp{0,1};
    vector<int> backup;
    for(int i=1;i<len;i++){
        backup=dp;
        if(A[i-1]>=A[i]||B[i-1]>=B[i]){
            dp[0]=backup[1];
            dp[1]=backup[0]+1;
        }else if(A[i-1]>=B[i]||B[i-1]>=A[i]){
            dp[0]=backup[0];
            dp[1]=backup[1]+1;
        }else{
            dp[0]=min(backup[0],backup[1]);
            dp[1]=min(backup[0],backup[1])+1;
        }
    }
    return min(dp[0],dp[1]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值