2321. 拼接数组的最大分数

79 阅读1分钟

题目:
给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,长度都是 n 。

你可以选择两个整数 left 和 right ,其中 0 <= left <= right < n ,接着 交换 两个子数组 nums1[left...right] 和 nums2[left...right] 。

  • 例如,设 nums1 = [1,2,3,4,5] 和 nums2 = [11,12,13,14,15] ,整数选择 left = 1 和 right = 2,那么 nums1 会变为 [1,12,13,4,5] 而 nums2 会变为 [11,2,3,14,15] 。

你可以选择执行上述操作 一次 或不执行任何操作。

数组的 分数 取 sum(nums1) 和 sum(nums2) 中的最大值,其中 sum(arr) 是数组 arr 中所有元素之和。

返回 可能的最大分数 。

子数组 是数组中连续的一个元素序列。arr[left...right] 表示子数组包含 nums 中下标 left 和 right 之间的元素 (含 下标 left 和 right 对应元素

算法:
方法一:动态规划 思路:从一般到特殊
假设交换[left, right]后,nums1是结果,交换后的元素为: max1 = nums1[0],nums1[1]...nums1[left - 1],nums2[left]...nums2[right],nums1[right + 1]...nums1[n - 1]

max1 = sum1 - sum(nums1, left, right) + sum(nums2, left, right)
= sum1 + (nums2[left] - nums1[left]) + ... (nums2[right] - nums1[right])
问题转换为求连续的子数组,(nums2[left] - nums1[left]) + ... (nums2[right] - nums1[right])的最大值。

同理求出max2,取max(max1, max2)就是结果

func maximumsSplicedArray(nums1 []int, nums2 []int) int {
    return max(slove(nums1, nums2), slove(nums2, nums1))
}


func slove(nums1, nums2 []int) int {
    pre, cur := nums2[0] - nums1[0], nums2[0] - nums1[0]
    n := len(nums1)
    maxSeqSum := cur
    sum := nums1[0]
    for i := 1; i < n; i ++ {
        sum = sum + nums1[i]
        diff := nums2[i] - nums1[i]
        cur = max(diff, diff + pre)
        pre = cur
        maxSeqSum = max(cur, maxSeqSum)
    }
    return sum + maxSeqSum
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}