topic
nums1
We 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 nums1
and 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:
- Relationship 1:
nums1[i] > nums1[i-1]
andnums2[i] > nums2[i-1]
- 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:
- Case 1: Satisfy relation 1, not satisfy relation 2
- Case 2: Does not satisfy relation 1, satisfies relation 2
- 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 immediatelynums1[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 immediatelynums2[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 largernums2[i]
thannums1[i-1]
andnums2[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;
}
}