LeetCode Medium Swaps To Make Sequences Increasing

We have two integer sequences A and B of the same non-zero length.

We are allowed to swap elements A[i] and B[i]. Note that both elements are in the same index position in their respective sequences.

At the end of some number of swaps, A and B are both strictly increasing. (A sequence is strictly increasing if and only if A[0] < A[1] < A[2] < ... < A[A.length - 1].)

Given A and B, return the minimum number of swaps to make both sequences strictly increasing. It is guaranteed that the given input always makes it possible.

Example:
Input: A = [1,3,5,4], B = [1,2,3,7]
Output: 1
Explanation: 
Swap A[3] and B[3].  Then the sequences are:
A = [1, 3, 5, 7] and B = [1, 2, 3, 4]
which are both strictly increasing.

Note:

  • A, B are arrays with the same length, and that length will be in the range [1, 1000].
  • A[i], B[i] are integer values in the range [0, 2000].

Solution

一次DP不能解决问题,如果DP是一个一维数组,DP[i]表示,在第i个位置上需要交换的最小次数,那么如何从DP[i-1]中推得DP[i]的值呢?
事实上,很难,考虑如下场景

0 4 4 5
0 1 6 8

这里我们可以交换1和4,也可以交换4和6,到底交换谁就不好说,如果交换1和4,那么交换次数为1,如果交换4和6,那么后续还要交换5和8,但是DP是从小问题推到大问题,我们无法从求DP[i-1]时就预知后面发生的事情

所以需要看两位,也就是i-1i,需要定义两个DP数组,分别表示当前需要交换和不需要交换两种状态

如果A[i-1] < A[i] && B[i-1] < B[i]的话,那么已经有序了
可以交换,也可以不交换:
i交换的话,则两个位置上的元素都要交换,才能保证交换后的序列依然有序,swap[i] = swap[i-1] + 1
ii 不交换的话,则noswap[i] = swap[i]

如果A[i-1] < B[i] && B[i-1] < A[i]的话,那么必须要交换,又有两种情况
i交换i位置,i-1位置不交换,则swap[i] = noswap[i-1] + 1
ii交换i-1位置,i位置不交换,则noswap[i] = swap[i-1]

#define min(a, b) (a) < (b) ? (a) : (b)

int minSwap(int* A, int ASize, int* B, int BSize) {
    const int n = ASize;
    int i;
    int swap[n], noswap[n];
    for (i = 0; i < n; i++) swap[i] = INT_MAX;
    for (i = 0; i < n; i++) noswap[i] = INT_MAX;
    swap[0] = 1;
    noswap[0] = 0;
    for (i = 1; i < n; i++) {
        if (A[i - 1] < A[i] && B[i - 1] < B[i]) {
            // Swapped A[i - 1] / B[i - 1], swap A[i] / B[i] as well 
            swap[i] = swap[i - 1] + 1;
            
            // Good case, no need swap for A[i] and B[i] 
            noswap[i] = noswap[i - 1];
        }
        if (A[i - 1] < B[i] && B[i - 1] < A[i]) {
            // A[i - 1] / B[i - 1] not swapped
            swap[i] = min(swap[i], noswap[i - 1] + 1);
            
            // Swap A[i - 1] / B[i - 1], not swap A[i] / B[i]
            noswap[i] = min(noswap[i], swap[i - 1]);
            
            // 用min的目的是假如在第一个if中也满足条件的话,取两者交换次数最小的
        }
    }
    return min(swap[n - 1], noswap[n - 1]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值