Minimum Swaps To Make Sequences Increasing 使序列递增的最小交换次数

我们有两个长度相等且不为空的整型数组 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);        
    }
};









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值