持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
1. 题目与解析
我们有两个长度相等且不为空的整型数组 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] 。
用例保证可以实现操作。
输入: nums1 = [1,3,5,4], nums2 = [1,2,3,7]
输出: 1
解释: 交换 A[3] 和 B[3] 后,两个数组如下: A = [1, 3, 5, 7] , B = [1, 2, 3, 4] 两个数组均为严格递增的。 示例 2:
输入: nums1 = [0,3,5,8,9], nums2 = [2,1,4,6,9]
输出: 1
看到题目大家应该都会浮现出dp的想法,但是可能简单思考之后,发现状态转移函数非常复杂,也就放弃了,这里,我们可以一起思考dp状态转移函数的分析过程,以更好的梳理与推广解题思路。
- 首先,我们可以知道,对于每一位
i,都只可能存在两种可能,交换了change或者是没有交换unchange; - 另外,我们需要保证,在
i位,我们不管是交换没交换,都需要保证截止到这一位满足序列递增,只有这样才能进行从i到i+1以至于所有位的推广。 - 因此我们分析
change[i]以及unchange[i]可以如何从第i-1位转移过来。 - 我们现非别考虑如何从
change[i-1]以及unchange[i-1]转移到change[i]以及unchange[i]。 - 考虑从
change[i-1]转移到change[i]:- 首先必须保证
nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i],否则不满足递增的条件 - 在上述条件的前提下,
change[i] = change[i-1] + 1
- 首先必须保证
- 考虑从
unchange[i-1]转移到change[i]:- 首先必须保证
nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i],否则不满足递增的条件 - 在上述条件的前提下,
change[i] = unchange[i-1] + 1
- 首先必须保证
- 考虑从
change[i-1]转移到unchange[i]:- 首先必须保证
nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i],否则不满足递增的条件 - 在上述条件的前提下,
unchange[i] = change[i-1]
- 首先必须保证
- 考虑从
unchange[i-1]转移到unchange[i]:- 首先必须保证
nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i],否则不满足递增的条件 - 在上述条件的前提下,
unchange[i] = unchange[i-1]
- 首先必须保证
- 上述转移过程涉及到两个条件:
nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i]- 针对这两个条件进行合并同类项就可以得到最后的状态转移方程
2. 题解
具体的题解如下所示:
class Solution {
public int minSwap(int[] nums1, int[] nums2) {
int ans = 0, change = 0, unchange = 0;
for (int i = 1; i < nums1.length; i++) {
int tmpChange = change, tmpUnchange = unchange;
boolean flg1 = nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i];
boolean flg2 = nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i];
if (flg1 && flg2) {
tmpChange = Math.min(unchange, change) + 1;
tmpUnchange = Math.min(unchange, change);
} else if (flg1 && !flg2) {
tmpChange = Math.max(change, 1) + 1;
tmpUnchange = unchange;
} else if (!flg1 && flg2) {
tmpChange = unchange + 1;
tmpUnchange = Math.max(change, 1);
}
change = tmpChange;
unchange = tmpUnchange;
}
return Math.min(change, unchange);
}
}