LeetCode-801.使序列递增的最小交换次数、动态规划的使用总结

我们有两个长度相等且不为空的整型数组 A 和 B 。我们可以交换 A[i] 和 B[i] 的元素。注意这两个元素在各自的序列中应该处于相同的位置。在交换过一些元素之后,数组 A 和 B 都应该是严格递增的(数组严格递增的条件仅为A[0] < A[1] < A[2] < … < A[A.length - 1])。给定数组 A 和 B ,请返回使得两个数组均保持严格递增状态的最小交换次数。假设给定的输入总是有效的。示例: 输入: A = [1,3,5,4], B = [1,2,3,7] 输出: 1
力扣(LeetCode)

确定状态

动态规划一般来讲,目标是求什么则什么即为状态,然后分析当前状态和之前状态的推导关系,进而进行穷举所有状态即可。
本题中使用dp[i][j] 表示第 i 个位置的元素,第 j (交换、不交换)状态时的最小次数。

初始状态

第 0 个位置可以交换,也可以不交换,即初始状态为:d[0][0] = 0、dp[0][1] = 1。

状态转移方程

根据题目要求一定存在结果,所以在第 i 个位置,有以下几种情况:
​①.A、B 两个数组对应的位置都是有序、存在交叉
在这里插入图片描述
如上图,A[i-1] < A[i] 、B[i-1] < B[i],并且 A[i-1] < B[i] 、B[i-1] < A[i];此时位置 i 可以交换,也可以不交换,并且和上个位置的交换状态无关。
②.A、B 两个数组对应的位置都是有序、不在交叉
在这里插入图片描述
如上图,A[i-1] < A[i] 、B[i-1] < B[i],并且 A[i-1] < B[i] 、B[i-1] > A[i];此时位置 i 若选择不交换,则上个位置也不能交换、若选择交换,则上个位置也必须交换。
③.A、B 两个数组对应的位置有一个存在无序
在这里插入图片描述
如上图,A[i-1] > A[i] 、B[i-1] < B[i],并且 A[i-1] < B[i] 、B[i-1] < A[i];此时位置 i 若选择不交换,则上个位置必须交换、若选择交换,并且上个位置不能交换。

确认结果

数组末尾位置的状态值就是本题为结果,即 min(dp[A.size()-1][0],dp[A.size()-1][1]);

代码示例

class Solution {
public:
    int minSwap(vector<int>& A, vector<int>& B) {
        int res = 0;
        vector<vector<int>> dp(A.size(),vector(2,0));
        dp[0][0] = 0;
        dp[0][1] = 1;
        for(int i = 1;i < A.size();i++)
        {
            if(A[i-1]<A[i]&&B[i-1]<B[i]){
                if(A[i-1]<B[i] && B[i-1]<A[i]){//任意交换或者不交换,取最优值
                    dp[i][0] = min(dp[i-1][0],dp[i-1][1]);
                    dp[i][1] = min(dp[i-1][0],dp[i-1][1])+1;
                }else{
                    dp[i][0] = dp[i-1][0];//不交换,则上个位置也不能交换
                    dp[i][1] = dp[i-1][1]+1; //交换,则上个位置也必须交换
                }
            }else{
                dp[i][0] = dp[i-1][1];// 不交换,则上个位置必须交换
                dp[i][1] = dp[i-1][0]+1;// 交换,则上个位置不能交换
            }
        }
        return min(dp[A.size()-1][0],dp[A.size()-1][1]);
    }
};

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值