[Leetcode] 801: The minimum number of exchanges to increase the sequence

topic

nums1We have two integer arrays and of equal length and not empty nums2. In one operation, we can swap elements of nums1[i]and .nums2[i]

  • For example, if nums1 = [1,2,3,8], nums2 = [5,6,7,4], you can swap the element at i = 3 to get nums1 = [1,2,3,4] and nums2 = [5,6,7,8] .

Returns the minimum number of operations required to make nums1and strictly increment. The array arr is strictly increasing and arr[0] < arr[1] < arr[2] < ... < arr[arr.length - 1].nums2

  • Notice:

    • A use case guarantees that an operation can be realized.
  • Example 1:

    • Input: nums1 = [1,3,5,4], nums2 = [1,2,3,7]
    • output: 1
    • Explanation:
      After exchanging A[3] and B[3], the two arrays are as follows:
      A = [1, 3, 5, 7], B = [1, 2, 3, 4]
      Both arrays are strictly increasing .
  • Example 2:

    • Input: nums1 = [0,3,5,8,9], nums2 = [2,1,4,6,9]
    • output: 1
  • hint:

    • 2 <= nums1.length <= 105
    • nums2.length == nums1.length
    • 0 <= nums1[i], nums2[i] <= 2 * 105

Source: LeetCode
Link: https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing
Copyright belongs to Leetcode Network. For personal study only, non-commercial use.

answer

Method 1: Dynamic programming
There is a hidden condition in this topic . There are only two possible relationships between the i-th element in the array and the i-1-th element in the array:

  1. Relationship 1:nums1[i] > nums1[i-1] andnums2[i] > nums2[i-1]
  2. Relationship 2:nums1[i] > nums2[i-1] andnums2[i] > nums1[i-1]

At least one of the relations must be satisfied, so that the two arrays are strictly monotonically increasing by exchanging the i-th element.
Therefore, the i-th element in the array must belong to one of three cases:

  1. Case 1: Satisfy relation 1, not satisfy relation 2
  2. Case 2: Does not satisfy relation 1, satisfies relation 2
  3. Case 3: Satisfy both relation 1 and relation 2

If any element does not belong to one of the above three cases, the two arrays cannot be strictly monotonically increasing by exchanging the i-th element. We can explain the three situations as follows:

  • Case 1:nums1[i] Be sure to follow immediately nums1[i-1]behind.
    • If bit i-1 swaps elements, then bit i must swap elements.
    • If the i-1th bit has no swap element, then the i-th bit must not swap elements.
  • Case 2:nums1[i] Be sure to follow immediately nums2[i-1]behind.
    • If bit i-1 swaps elements, then bit i must not swap elements.
    • If the i-1th bit has no swap element, then the i-th bit must swap elements.
  • Case 3:nums1[i] and are larger nums2[i]than nums1[i-1]and nums2[i-1], therefore:
    • If the i-1th element is swapped, the i-th element may or may not be swapped.
    • If the i-1th element is not exchanged, the i-th element can also be exchanged or not.

We found that there are only two operations for elements of each bit: exchange and non-exchange elements, and whether the i-th element is exchanged is related to the i-1-th element, we can use an array to store information int[][]dp = new [len-1][2]. in:

  • dp[i][0]Indicates the minimum number of operations required to make two arrays strictly monotonically recursive without swapping elements at the i-th position.
  • dp[i][1]Indicates the minimum number of operations required to make two arrays strictly monotonically recursive when swapping elements at the i-th position.

Through the above analysis, we can find the derivation rules :

  • Case 1:
    • dp[i][0] = dp[i-1][0];
    • dp[i][1] = dp[i-1][1] + 1;
  • Case two:
    • dp[i][0] = dp[i-1][1];
    • dp[i][1] = dp[i-1][0] + 1;
  • Case three:
    • dp[i][0] = Math.min(dp[i-1][0], dp[i-1][1]);
    • dp[i][1] = Math.min(dp[i-1][0], dp[i-1][1]) + 1;
class Solution {
    
    
    public int minSwap(int[] nums1, int[] nums2) {
    
    
        int len = nums1.length;
        int[][] dp = new int[len][2];
        dp[0][0] = 0;
        dp[0][1] = 1;

        for (int i = 1; i < len; i++){
    
    
            if (case1(i, nums1, nums2) && !case2(i, nums1, nums2)){
    
    
                dp[i][0] = dp[i-1][0];
                dp[i][1] = dp[i-1][1] + 1;
            }else if (!case1(i, nums1, nums2) && case2(i, nums1, nums2)){
    
    
                dp[i][0] = dp[i-1][1];
                dp[i][1] = dp[i-1][0] + 1;
            }else{
    
    
                dp[i][0] = Math.min(dp[i-1][0], dp[i-1][1]);
                dp[i][1] = Math.min(dp[i-1][0], dp[i-1][1]) + 1;
            }
        }

        return dp[len-1][0] > dp[len-1][1] ? dp[len-1][1] : dp[len-1][0];
    }

    public boolean case1(int i, int[] nums1, int[] nums2){
    
    
        if (nums1[i] > nums1[i-1] && nums2[i] > nums2[i-1])
            return true;
        return false;
    }

    public boolean case2(int i, int[] nums1, int[] nums2){
    
    
        if (nums1[i] > nums2[i-1] && nums2[i] > nums1[i-1])
            return true;
        return false;
    }
}

Guess you like

Origin blog.csdn.net/weixin_45800258/article/details/127246985