Leetcode-801. Minimum Swaps To Make Sequences Increasing 使序列递增的最小交换次数 (DP)

给定两个长度相等的整数数组A和B,可以通过交换A[i]和B[i]来使它们严格递增。目标是最小化交换次数。本文介绍了使用动态规划解决此问题的方法,分析了复杂度并提供了示例解释。

题目

我们有两个长度相等且不为空的整型数组 A 和 B 。
我们可以交换 A[i] 和 B[i] 的元素。注意这两个元素在各自的序列中应该处于相同的位置。
在交换过一些元素之后,数组 A 和 B 都应该是严格递增的(数组严格递增的条件仅为A[0] < A[1] < A[2] < … < A[A.length - 1])。
给定数组 A 和 B ,请返回使得两个数组均保持严格递增状态的最小交换次数。假设给定的输入总是有效的。
链接:https://leetcode.com/problems/minimum-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.

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].

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.

思路及代码

DP
  • swap[i]表示第i位交换使得A[0]-A[i],B[0]-B[i]都是严格单调递增的最小交换次数
  • keep[i]表示第i位不交换使得A[0]-A[i],B[0]-B[i]都是严格单调递增的最小交换次数
  • 在考虑第i位是否交换时,看第i-1位和第i位的元素大小,分为多种情况
    • A[i-1] < A[i] and B[i-1] < B[i],表示原来就是符合条件的,所有如果第i-1位交换的话,第i位也要交换,即swap[i] = swap[i-1] + 1;如果第i-1位没有交换的话,第i位也保持不变即可,即keep[i] = keep[i-1]
    • A[i-1] < B[i] and B[i-1] < A[i]表述交换后可以符合单调递增的条件,这里分为两种可能
      • A=[2,8],B=[5,4],即必须要交换
        • swap[i] = keep[i-1] + 1
        • keep[i] = swap[i-1]
      • A=[2,5],B=[3,4],即交换与否都可以
        • 若交换,则同上一种情况一样
        • 若不交换,则之前已经考虑过了(A[i-1] < A[i] and B[i-1] < B[i])
        • 所以这两者取最小值即可
  • 返回swap和keep最终值的最小值即可
class Solution:
    def minSwap(self, A: List[int], B: List[int]) -> int:
        swap1, keep1 = 1, 0
        for i in range(1,len(A)):
            swap2 = keep2 = float("inf")
            if A[i-1] < A[i] and B[i-1] < B[i]:
                swap2 = swap1 + 1
                keep2 = keep1
            if A[i-1] < B[i] and B[i-1] < A[i]:
                swap2 = min(swap2, keep1 + 1)
                keep2 = min(keep2, swap1)
            swap1, keep1 = swap2, keep2
        return min(swap1, keep1)

复杂度

T = O(n)O(n)O(n)
S = O(1)O(1)O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值