使序列递增的最小交换次数
难度:
标签:
题目描述
代码结果
运行时间: 87 ms, 内存: 30.6 MB
/*
* Problem: We have two equal-length integer arrays nums1 and nums2 that are not empty. In one operation, we can swap nums1[i] and nums2[i].
* Goal: Return the minimum number of operations needed to make both nums1 and nums2 strictly increasing.
* Explanation: Two arrays arr are strictly increasing if arr[0] < arr[1] < arr[2] < ... < arr[arr.length - 1].
* Constraints: It is guaranteed that it is possible to achieve the goal.
*/
import java.util.stream.IntStream;
public class Solution {
public int minSwap(int[] nums1, int[] nums2) {
int n = nums1.length;
int[] keep = new int[n]; // Minimum swaps to make arrays increasing if we don't swap at i
int[] swap = new int[n]; // Minimum swaps to make arrays increasing if we swap at i
keep[0] = 0;
swap[0] = 1;
IntStream.range(1, n).forEach(i -> {
keep[i] = swap[i] = n; // Initialize with a large number
// Condition if current elements are already in increasing order without swapping
if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1]) {
keep[i] = keep[i - 1];
swap[i] = swap[i - 1] + 1;
}
// Condition if current elements will be in increasing order if swapped
if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) {
keep[i] = Math.min(keep[i], swap[i - 1]);
swap[i] = Math.min(swap[i], keep[i - 1] + 1);
}
});
return Math.min(keep[n - 1], swap[n - 1]);
}
}
解释
方法:
这个题解使用了动态规划的思想。定义了两个变量a和b,分别表示当前位置i不交换和交换时的最小交换次数。然后从第二个位置开始遍历数组,对于每个位置,根据前一个位置的状态和当前位置的大小关系,更新a和b的值。最后返回a和b中的较小值即为最小交换次数。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在动态规划中,`a`和`b`变量的初始值为什么分别设置为0和1,这样的设置有什么特别的意义吗?
▷🦆
在代码中,为什么当`nums1[i - 1] >= nums1[i]`或`nums2[i - 1] >= nums2[i]`时,选择将`a`和`b`的值设置为`y`和`x + 1`?这样的逻辑是基于什么考虑?
▷🦆
题解中提到当`nums1[i - 1] < nums2[i]`和`nums2[i - 1] < nums1[i]`时,可以选择交换或不交换,这种情况下的决策影响如何体现在代码中?
▷🦆
为什么在循环的每一步中,都需要重新计算`a`和`b`,而不能直接从前一个位置的结果推断出当前位置的最优解?
▷