困难题452 最小移动次数使数组相等 | 豆包MarsCode AI刷题

59 阅读3分钟

问题描述

小C有两个长度为 N 的数组 A 和 B。他可以进行以下两种操作,来将数组 A 转换为数组 B

  1. 反转数组 A,即使数组 A 的元素顺序完全颠倒。
  2. 在 [1, N] 范围内选择一个整数 i,然后可以对 A[i] 添加或减去任意值。

你的任务是帮助小C找到使数组 A 等于数组 B 所需的最小操作次数。

例如:当 N = 3A = [1, 2, 5]B = [4, 2, 1] 时,最佳操作如下:

  • 第一步反转数组 A,得到新数组 A = [5, 2, 1]
  • 第二步从位置 1 减去 1,得到新数组 A = [4, 2, 1]
    因此,答案是 2

测试样例

样例1:

输入:N = 3,A = [1, 2, 5],B = [4, 2, 1]
输出:2

样例2:

输入:N = 4,A = [7, 8, 6, 2],B = [6, 2, 8, 7]
输出:3

样例3:

输入:N = 2,A = [3, 9],B = [9, 3]
输出:1

要解决这个问题,我们可以考虑以下几个步骤:

解题思路

  1. 理解问题

    • 我们需要将数组 A 转换为数组 B
    • 可以进行的操作有两种:反转数组 A 和修改数组 A 中的某个元素。
  2. 分析操作

    • 反转操作:反转数组 A 的成本是固定的,即一次操作。
    • 修改操作:修改数组 A 中的某个元素的成本取决于元素的差异。
  3. 策略

    • 首先,我们可以尝试不反转数组 A,直接计算将 A 转换为 B 所需的最小修改次数。
    • 然后,我们尝试反转数组 A,再计算将反转后的数组转换为 B 所需的最小修改次数。
    • 最后,比较这两种情况的操作次数,取最小值。
  4. 具体步骤

    • 计算不反转数组 A 时的最小修改次数。
    • 计算反转数组 A 后的最小修改次数。
    • 比较两种情况的操作次数,取最小值。

伪代码框架

def solution(N: int, A: list, B: list) -> int:
    # 计算不反转数组 A 时的最小修改次数
    def min_modifications(A, B):
        # 计算将 A 转换为 B 所需的最小修改次数
        pass

    # 计算反转数组 A 后的最小修改次数
    def min_modifications_reversed(A, B):
        # 反转数组 A
        reversed_A = A[::-1]
        # 计算将反转后的 A 转换为 B 所需的最小修改次数
        pass

    # 计算不反转数组 A 时的最小修改次数
    min_mods_direct = min_modifications(A, B)
    
    # 计算反转数组 A 后的最小修改次数
    min_mods_reversed = min_modifications_reversed(A, B)
    
    # 返回两种情况的最小值
    return min(min_mods_direct, min_mods_reversed + 1)  # +1 是因为反转操作需要一次

if __name__ == '__main__':
    print(solution(N = 3, A = [1, 2, 5], B = [4, 2, 1]) == 2)
    print(solution(N = 4, A = [7, 8, 6, 2], B = [6, 2, 8, 7]) == 3)
    print(solution(N = 2, A = [3, 9], B = [9, 3]) == 1)

关键步骤

  • min_modifications(A, B):计算将 A 转换为 B 所需的最小修改次数。
  • min_modifications_reversed(A, B):计算将反转后的 A 转换为 B 所需的最小修改次数。
  • 比较两种情况的操作次数:取最小值,并考虑反转操作的成本。

通过这种方式,我们可以有效地找到使数组 A 等于数组 B 所需的最小操作次数。

完整代码

def solution(N: int, A: list, B: list) -> int:
    # 计算不反转数组 A 时的最小修改次数
    def min_modifications(A, B):
        count = 0
        for i in range(N):
            if A[i] != B[i]:
                count += 1
        return count

    # 计算反转数组 A 后的最小修改次数
    def min_modifications_reversed(A, B):
        reversed_A = A[::-1]
        return min_modifications(reversed_A, B)

    # 计算不反转数组 A 时的最小修改次数
    min_mods_direct = min_modifications(A, B)
    
    # 计算反转数组 A 后的最小修改次数
    min_mods_reversed = min_modifications_reversed(A, B)
    
    # 返回两种情况的最小值
    return min(min_mods_direct, min_mods_reversed + 1)  # +1 是因为反转操作需要一次

if __name__ == '__main__':
    print(solution(N = 3, A = [1, 2, 5], B = [4, 2, 1]) == 2)
    print(solution(N = 4, A = [7, 8, 6, 2], B = [6, 2, 8, 7]) == 3)
    print(solution(N = 2, A = [3, 9], B = [9, 3]) == 1)