我们有两个长度相等且不为空的整型数组 A
和 B
。
我们可以交换 A[i]
和 B[i]
的元素。注意这两个元素在各自的序列中应该处于相同的位置。
在交换过一些元素之后,数组 A
和 B
都应该是严格递增的(数组严格递增的条件仅为A[0] < A[1] < A[2] < ... < A[A.length - 1]
)。
给定数组 A
和 B
,请返回使得两个数组均保持严格递增状态的最小交换次数。假设给定的输入总是有效的。
示例: 输入: A = [1,3,5,4], B = [1,2,3,7] 输出: 1 解释: 交换 A[3] 和 B[3] 后,两个数组如下: A = [1, 3, 5, 7] , B = [1, 2, 3, 4] 两个数组均为严格递增的。
注意:
A, B
两个数组的长度总是相等的,且长度的范围为[1, 1000]
。A[i], B[i]
均为[0, 2000]
区间内的整数。
思路:这道题采用动态规划,维护两个数组swapOperation表示对于第i个元素A和B,最小的交换次数是我们交换A[i]和B[i],fixOperation表示对于第i个元素A和B,最小的交换次数是我们不交换A[i]和B[i]。
来看下面这个例子:
index 0 1 2 3 4
A 1 3 5 4 9
B 1 2 3 7 10
swapRecord 1 1 2 1 2
fixRecord 0 0 0 2 1
我们来看是如何更新swapOperation和fixOperation的,首先初始化swapOperation=1,fixOperation=0
对于i=1,是否交换都可以(后面会解释为什么),所以我们取前面两个操作最小的值,min=min(swapOperation,fixOperation)=0,所以swapOpearition=min+1=1,fixOperation=min=0
对于i=2,由于A[1]>=B[2],所以A[2]和B[2]的操作应该和A[1]和B[1]一样,因为A[1]>=B[2],所以B[2]不能和A[1]在一个数组中,即如果A[1],B[1]交换了,那么A[2]和B[2]也必须交换,这样才能保证A[1]和B[2]不在一个数组里。所以在这种情况下:swapOperation=swapOpration+1,fixOperation=fixOperation
对于i=3,由于A[2]>=A[3]所以A[2]和A[3]不能在一个组里,根据上面的解释A[3]和A[2]应该是相反的操作,所以swapOperation=fixOperation+1,fixOperation=swapOperation
对于i=4,由于都不满足上面的条件,所以交不交换都可以,但是定义的swapOperation是对于第i个元素必须交换,fixOperation是一定不交换,所以swapOperaion可以在上一次i-1次即swapOperation和fixOperation中选择一个较小的值然后加1(加一代表这次一定交换),而fixOperation直接选取较小的值即可。
经过上面的分析,最后返回swapOperation和fixOperation中较小的那个值即可。
参考代码:
class Solution {
public:
int minSwap(vector<int>& A, vector<int>& B) {
int swapOperation = 1;
int fixOperation = 0;
int n = A.size();
for (int i = 1; i < n; i++) {
if (A[i - 1] >= B[i] || B[i - 1] >= A[i]) {
swapOperation++;
fixOperation = fixOperation;
}
else if (A[i - 1] >= A[i] || B[i - 1] >= B[i]) {
int tmp = swapOperation;
swapOperation = fixOperation + 1;
fixOperation = tmp;
}
else {
int tmp = min(swapOperation, fixOperation);
swapOperation = tmp + 1;
fixOperation = tmp;
}
}
return min(swapOperation,fixOperation);
}
};