801. 使序列递增的最小交换次数(Python)

难度:★★★★☆
类型:数组
方法:动态规划

力扣链接请移步本题传送门
更多力扣中等题的解决方案请移步力扣中等题目录

题目

我们有两个长度相等且不为空的整型数组 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]区间内的整数。

解答

我们使用动态规划来解决这个问题。

设数组dp维度为len(A)*2,dp[i][0]表示A[:i+1]和B[:i+1]两个子数组不交换最后一个元素时所需要的满足题目要求的最小交换次数,dp[i][0]表示A[:i+1]和B[:i+1]两个子数组交换最后一个元素时所需要的满足题目要求的最小交换次数,dp中所有元素初始化为无穷,并根据规则将第一排填充0和1。

根据下标遍历两个数组,如果A[i-1] < A[i]且B[i-1] < B[i],说明A[:i+1]和B[:i+1]两个子数组不需要交换最后一个元素就已经可以满足均严格递增了,根据能少交换就少交换的原则,暂且不必继续做交换,因此状态转移方程为:

            dp[i][0] = dp[i-1][0]
            dp[i][1] = dp[i-1][1]+1

如果A[i-1] < B[i]且B[i-1] < A[i],说明A[:i+1]和B[:i+1]两个子数组的最后一位元素可以相互交换,可以比较一下相互交换后是否可以达到更少的交换次数。

            dp[i][0] = min(dp[i][0], dp[i-1][1])
            dp[i][1] = min(dp[i][1], dp[i-1][0]+1)

最终选择dp[-1]中的最小值即可。

class Solution(object):
    def minSwap(self, A, B):
        dp = [[float('inf') for _ in range(2)] for _ in range(len(A))]
        dp[0][0], dp[0][1] = 0, 1
        for i in range(1, len(A)):
            if A[i-1] < A[i] and B[i-1] < B[i]:
                dp[i][0] = dp[i-1][0]
                dp[i][1] = dp[i-1][1]+1
            if A[i-1] < B[i] and B[i-1] < A[i]:
                dp[i][0] = min(dp[i][0], dp[i-1][1])
                dp[i][1] = min(dp[i][1], dp[i-1][0]+1)
        print(dp)
        return min(dp[-1])

如有疑问或建议,欢迎评论区留言~

有关更多力扣中等题的python解决方案,请移步力扣中等题解析

你可能感兴趣的:(801. 使序列递增的最小交换次数(Python))