算法小知识-----10.10----- 使序列递增的最小交换次数

112 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

真真正正的周一了,家人们,仿佛已经过了好久了.今天在一次挑战自己的软肋

使序列递增的最小交换次数

该题出自力扣的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] 。 返回 使 nums1 和 nums2 严格递增 所需操作的最小次数 。 数组 arr 严格递增 且  arr[0] < arr[1] < arr[2] < ... < arr[arr.length - 1] 。

  • 虽然是困难题,但归根结底也算是中等题,因为就是两个int数组之间的比较。
  • 给出两个int数组,最终返回两个int数组都为严格递增数组所需要的次数。并且只能替换相同下标的两个数组位置
  • 利用动态规划的思路,开辟一个二维数组,遍历数组
    • 首先确定,每次只会存在两种情况,变或者不变。
    • 在nums1[i] >nums1[i -1] && nums2[i] > nums2[i -1]的情况下
      • 如果不变,则取当前值与前一位不变作最小值比较
      • 如果变的话,则取当前值与上一位变化的 加一作比较
    • nums1[i] > nums2[i -1] && nums2[i] > nums1[i -1]的情况下,默认需要做出转换
      • 如果不变的话,那么上一位就需要做出变化
      • 如果变的话,那么上一位的比较最小值
    • 最终返回二维数组的最后一位的最小值比较

编码

class Solution {
    public int minSwap(int[] nums1, int[] nums2) {
        int len = nums1.length;
        int[][] dp = new int[2][len];
        for (int inner[] : dp) {
            Arrays.fill(inner, Integer.MAX_VALUE);
        }
        dp[0][0] = 0;
        dp[1][0] = 1;
        for (int i = 1; i < len; i++) {
            // 情况1:i 和 i -1 变或不变
            //情况2:变的情况下,i变和 i-1变
            if (nums1[i] >nums1[i -1] && nums2[i] > nums2[i -1]){
                // 不变
                dp[0][i] = Math.min(dp[0][i],dp[0][i - 1]);
                // 变
                dp[1][i] = Math.min(dp[1][i],dp[1][i - 1] + 1);
            }

            //A=[1 3 3]
            //B=[1 2 4]
            if (nums1[i] > nums2[i -1] && nums2[i] > nums1[i -1]){
                dp[0][i] = Math.min(dp[0][i],dp[1][i -1]);
                dp[1][i] = Math.min(dp[1][i],dp[0][i - 1] + 1);
            }

        }
        return Math.min(dp[0][len -1],dp[1][len -1]);
    }
}

image.png