力扣 801. 使序列递增的最小交换次数

题目来源:https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/

大致题意:
给两个数组 nums1 和 nums2,一次交换操作可以交换相同索引处两个数组的元素,求最少需要交换多少次可以使两个数组都递增

如 [1, 5, 4, 8] 和 [2, 3, 6, 9],可以交换索引 2 处元素,使两个数组变为 [1, 5, 6, 8] 和 [2, 3, 4, 9],这样只交换一次两个数组都满足递增

题目保证两个数组能在交换一定次数后都递增

思路

首先分析两个数组当前位置元素与上一个位置元素的关系,有以下几种

  1. nums1[i] > nums1[i - 1] 且 nums2[i] > nums2[i - 1],这种情况不需要交换即满足递增。如果上一位交换了,那么当前位也需要交换
  2. nums1[i] > nums1[i - 1] 且 nums2[i] > nums2[i - 1],这种情况需要交换当前位才满足递增,如果上一位交换了,那么当前位不需要交换
  3. nums1[i] > nums1[i - 1] 且 nums2[i] > nums2[i - 1],同时 nums1[i] > nums1[i - 1],nums2[i] > nums2[i - 1],这种情况不管上一位交换与否都满足递增

于是可以使用两个标志位 unChange 和 change 表示上一位不交换和交换满足递增所需的最小次数

那么对于上述三种情况(第三种情况包含在前两种的判断中),unChange 和 change 的更新方法为

  1. 使用 unChangeTemp 和 changeTemp,表示本轮操作后不交换和交换满足递增所需的最小次数,初始设置为最大值 n
  2. 首先判断如果满足第一个条件,那么 unChangeTemp 即为上一轮不交换的次数,changeTemp 更新为上一轮交换次数 + 1
  3. 之后判断如果满足第二个条件,那么 unChangeTemp 为当前值与上一轮交换次数的最小值(因为当前值可能在上一个判断中更新,即考虑第三个条件,两种情况都满足时的判断),changeTemp 更新为上一轮不交换次数 + 1 与当前值的最小值 (因为当前值可能在上一个判断中更新,即考虑第三个条件,两种情况都满足时的判断)
  4. 然后根据 unChangeTemp 和 changeTemp 更新标志位 unChange 和 change

最终返回标志位 unChange 和 change 的最小值即可

具体看代码:

class Solution {
    public int minSwap(int[] nums1, int[] nums2) {
        int n = nums1.length;
        int unChange = 0;
        int change = 1;   // 初始时,交换首位元素,操作次数为 1
        for (int i = 1; i < n; i++) {
            // 初始化当前位递增的最小交换次数
            int unChangeTemp = n;
            int changeTemp = n;
            // 如果不交换就满足递增
            if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) {
                // 当前位不交换就满足递增
                // 当前位不交换的操作次数与上一轮相同
                unChangeTemp = unChange;
                // 上一位交换了,当前位交换才能满足递增,操作次数为上一轮交换次数 + 1
                changeTemp = change + 1;
            }
            // 如果交换后才满足递增
            if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) {
                // 当前位必须交换,或者上一位交换才满足递增
                // 当前位不交换,上一位交换
                unChangeTemp = Math.min(unChangeTemp, change);
                // 当前位交换,上一位不交换
                changeTemp = Math.min(unChange + 1, changeTemp);
            }
            change = changeTemp;
            unChange = unChangeTemp;
        }
        return Math.min(change, unChange);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三更鬼

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值