【leetcode】【2022/10/10】801. 使序列递增的最小交换次数

问题描述:

  • 我们有两个长度相等且不为空的整型数组 nums1 和 nums2
    • 在一次操作中,我们可以交换 nums1[i] 和 nums2[i] 的元素
    • 例如,如果 nums1 = [1,2,3,8], nums2 =[5,6,7,4],你可以交换 i = 3 处的元素,得到 nums1 =[1,2,3,4]nums2 =[5,6,7,8]
    • 返回使 nums1nums2 严格递增所需操作的最小次数。
  • 用例保证可以实现操作。

核心思路:

  • 要注意的点很多:
    1. 交换操作只能交换两个数组同一个位置的值。
    2. 用例保证最后两个数组是可以实现严格递增的。
  • 由前面注意的点可以推断出:【假设 a = nums1[i], b = nums1[i-1], c = nums2[i], d = nums2[i-1]
    • 在当前位置 a >= b and a >= d 且两个等号不会同时成立,同理 c >= b and c >= d
    • 假设 a == b,则必定有 a > d (反过来不成立),此时只能够选择交换,而不能够选择保持原样(也就是不能选择不交换);假若 a == d,则必定不能够选择交换;如果 a > b and a > d 则可以选择交换也可以选择不交换。
    • 因此考虑用动态规划来解决此题,增多一个状态,新状态为交换操作,也就是 dp[i][0] 代表不交换操作,dp[i][1] 代表交换操作,如果 a > b and a > d,则状态转移的情况为 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

代码实现:

class Solution
{
public:
    int minSwap(vector<int>& nums1, vector<int>& nums2)
    {
        int m = nums1.size();
        vector<vector<int>> dp(m, vector<int>(2, INT_MAX));
        dp[0][0] = 0, dp[0][1] = 1;
        for(int i = 1; i < m; ++i)
        {
            int a = nums1[i-1], b = nums1[i];
            int c = nums2[i-1], d = nums2[i];
            if(a < b and c < d) // 这种判断是为了避免 a == b or c == d 的情况
                dp[i][0] = dp[i-1][0] ,dp[i][1] = dp[i-1][1]+1;
            if(a < d and c < b)
            {
                dp[i][0] = min(dp[i][0], dp[i-1][1]);
                dp[i][1] = min(dp[i][1], dp[i-1][0]+1);
            }
        }
        return min(dp[m-1][0], dp[m-1][1]);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值