持续创作,加速成长!这是我参与「掘金日新计划 · 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]);
}
}