跳转至

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

题目描述

我们有两个长度相等且不为空的整型数组 nums1 和 nums2 。在一次操作中,我们可以交换 nums1[i] 和 nums2[i]的元素。

  • 例如,如果 nums1 = [1,2,3,8]nums2 =[5,6,7,4] ,你可以交换 i = 3 处的元素,得到 nums1 =[1,2,3,4]nums2 =[5,6,7,8]

返回 使 nums1nums2 严格递增 所需操作的最小次数

数组 arr 严格递增 且  arr[0] < arr[1] < arr[2] < ... < arr[arr.length - 1] 。

注意:

  • 用例保证可以实现操作。

 

示例 1:

输入: nums1 = [1,3,5,4], nums2 = [1,2,3,7]
输出: 1
解释: 
交换 A[3] 和 B[3] 后,两个数组如下:
A = [1, 3, 5, 7] , B = [1, 2, 3, 4]
两个数组均为严格递增的。

示例 2:

输入: nums1 = [0,3,5,8,9], nums2 = [2,1,4,6,9]
输出: 1

 

提示:

  • 2 <= nums1.length <= 105
  • nums2.length == nums1.length
  • 0 <= nums1[i], nums2[i] <= 2 * 105

解法

方法一:动态规划

定义 \(a\), \(b\) 分别表示使得下标 \([0..i]\) 的元素序列严格递增,且第 \(i\) 个元素不交换、交换的最小交换次数。下标从 \(0\) 开始。

\(i=0\) 时,有 \(a = 0\), \(b=1\)

\(i\gt 0\) 时,我们先将此前 \(a\), \(b\) 的值保存在 \(x\), \(y\) 中,然后分情况讨论:

如果 \(nums1[i - 1] \ge nums1[i]\) 或者 \(nums2[i - 1] \ge nums2[i]\),为了使得两个序列均严格递增,下标 \(i-1\)\(i\) 对应的元素的相对位置必须发生变化。也就是说,如果前一个位置交换了,那么当前位置不交换,因此有 \(a = y\);如果前一个位置没有交换,那么当前位置必须交换,因此有 \(b = x + 1\)

否则,下标 \(i-1\)\(i\) 对应的元素的相对位置可以不发生变化,那么有 \(b = y + 1\)。另外,如果满足 \(nums1[i - 1] \lt nums2[i]\) 并且 \(nums2[i - 1] \lt nums1[i]\),那么下标 \(i-1\)\(i\) 对应的元素的相对位置可以发生变化,此时 \(a\)\(b\) 可以取较小值,因此有 \(a = \min(a, y)\)\(b = \min(b, x + 1)\)

最后,返回 \(a\)\(b\) 中较小值即可。

时间复杂度 \(O(n)\),空间复杂度 \(O(1)\)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution:
    def minSwap(self, nums1: List[int], nums2: List[int]) -> int:
        a, b = 0, 1
        for i in range(1, len(nums1)):
            x, y = a, b
            if nums1[i - 1] >= nums1[i] or nums2[i - 1] >= nums2[i]:
                a, b = y, x + 1
            else:
                b = y + 1
                if nums1[i - 1] < nums2[i] and nums2[i - 1] < nums1[i]:
                    a, b = min(a, y), min(b, x + 1)
        return min(a, b)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int minSwap(int[] nums1, int[] nums2) {
        int a = 0, b = 1;
        for (int i = 1; i < nums1.length; ++i) {
            int x = a, y = b;
            if (nums1[i - 1] >= nums1[i] || nums2[i - 1] >= nums2[i]) {
                a = y;
                b = x + 1;
            } else {
                b = y + 1;
                if (nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i]) {
                    a = Math.min(a, y);
                    b = Math.min(b, x + 1);
                }
            }
        }
        return Math.min(a, b);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
    int minSwap(vector<int>& nums1, vector<int>& nums2) {
        int a = 0, b = 1, n = nums1.size();
        for (int i = 1; i < n; ++i) {
            int x = a, y = b;
            if (nums1[i - 1] >= nums1[i] || nums2[i - 1] >= nums2[i]) {
                a = y, b = x + 1;
            } else {
                b = y + 1;
                if (nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i]) {
                    a = min(a, y);
                    b = min(b, x + 1);
                }
            }
        }
        return min(a, b);
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
func minSwap(nums1 []int, nums2 []int) int {
    a, b, n := 0, 1, len(nums1)
    for i := 1; i < n; i++ {
        x, y := a, b
        if nums1[i-1] >= nums1[i] || nums2[i-1] >= nums2[i] {
            a, b = y, x+1
        } else {
            b = y + 1
            if nums1[i-1] < nums2[i] && nums2[i-1] < nums1[i] {
                a = min(a, y)
                b = min(b, x+1)
            }
        }
    }
    return min(a, b)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function minSwap(nums1: number[], nums2: number[]): number {
    let [a, b] = [0, 1];
    for (let i = 1; i < nums1.length; ++i) {
        let x = a,
            y = b;
        if (nums1[i - 1] >= nums1[i] || nums2[i - 1] >= nums2[i]) {
            a = y;
            b = x + 1;
        } else {
            b = y + 1;
            if (nums1[i - 1] < nums2[i] && nums2[i - 1] < nums1[i]) {
                a = Math.min(a, y);
                b = Math.min(b, x + 1);
            }
        }
    }
    return Math.min(a, b);
}

评论

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy