📌  相关文章
📜  给定两个数组的最小总和(1)

📅  最后修改于: 2023-12-03 15:27:34.518000             🧑  作者: Mango

给定两个数组的最小总和

问题描述

给定两个数组nums1nums2,并且它们的长度都为$n$,现在定义一个函数$f(i, j)$,其中$0\le i,j<n$,$f(i, j)$表示选择$nums1$中下标小于等于$i$的元素和$nums2$中下标小于等于$j$的元素,并且这些元素中的最小值之和。例如,$f(0, 0)$表示选择$nums1$中第$0$个元素和$nums2$中第$0$个元素,并且这些元素中的最小值为$min(nums1[0], nums2[0])$。现在的问题是如何找到一个函数$f$,使得$f(n-1, n-1)$得到的结果是最小的。

解题思路

可以使用动态规划的思想,假设已经得到了$f(i-1, j)$和$f(i, j-1)$,考虑如何求出$f(i, j)$,根据$f$的定义,选择$nums1$中下标小于$i$的元素和$nums2$中下标小于等于$j$的元素中的最小值,或者选择$nums1$中下标小于等于$i$的元素和$nums2$中下标小于$j$的元素中的最小值,则$f(i, j)$可表示为:

$f(i, j)=min(f(i-1, j) + nums1[i], f(i, j-1) + nums2[j])$,其中$0\le i,j<n$,$f(0, 0)=nums1[0]+nums[0]$

最后,$f(n-1, n-1)$即为选择$nums1$和$nums2$中最小值之和的最小值。

代码实现
def min_sum_of_two_arrays(nums1: List[int], nums2: List[int]) -> int:
    n = len(nums1)
    dp = [[float("inf")] * n for _ in range(n)]  # 初始化dp数组为正无穷
    dp[0][0] = nums1[0] + nums2[0]  # 初始化dp[0][0]
    for i in range(1, n):
        dp[i][0] = min(dp[i-1][0] + nums1[i], nums1[i]+nums2[0])
        dp[0][i] = min(dp[0][i-1] + nums2[i], nums1[0]+nums2[i])
    for i in range(1, n):
        for j in range(1, n):
            dp[i][j] = min(dp[i-1][j] + nums1[i],   # 选择nums1[i]
                           dp[i][j-1] + nums2[j],   # 选择nums2[j]
                           min(nums1[i], nums2[j])) # 既不选择nums1[i]也不选择nums2[j]
    return dp[n-1][n-1]   # 返回结果
复杂度分析
  • 时间复杂度:$O(n^2)$,其中$n$为数组的长度,需要计算$n^2$次$f(i,j)$。
  • 空间复杂度:$O(n^2)$,需要使用一个二维数组$dp$来存储中间结果。