拼接数组的最大分数

151 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

说在前面

🎈每天进行一道算法题目练习,今天的题目是“拼接数组的最大分数”。

问题描述

给你两个下标从 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 对应元素)。

示例 1:

输入:nums1 = [60,60,60], nums2 = [10,90,10]
输出:210
解释:选择 left = 1right = 1 ,得到 nums1 = [60,90,60] 和 nums2 = [10,60,10] 。
分数为 max(sum(nums1), sum(nums2)) = max(210, 80) = 210

示例 2:

输入:nums1 = [20,40,20,70,30], nums2 = [50,20,50,40,20]
输出:220
解释:选择 left = 3right = 4 ,得到 nums1 = [20,40,20,40,20] 和 nums2 = [50,20,50,70,30] 。
分数为 max(sum(nums1), sum(nums2)) = max(140, 220) = 220

示例 3:

输入:nums1 = [7,11,13], nums2 = [1,1,1]
输出:31
解释:选择不交换任何子数组。
分数为 max(sum(nums1), sum(nums2)) = max(31, 3) = 31

提示:

n == nums1.length == nums2.length
1 <= n <= 10^5
1 <= nums1[i], nums2[i] <= 10^4

思路分析

首先我们要先理解题意,题目的意思是会给我们两个数组,我们需要找到两个端点leftright,交换 两个子数组 nums1[left...right] 和 nums2[left...right],使得交换了子数组后的数组元素总和最大。

我们先来看一下两个数组交换了子数组之后,他们的和会有什么变化: 设num1.length = num2.length = n

  • 1、原本num1的数组元素之和
sum1 = num1[0] + num1[1] + ... + num1[n-2] + num1[n-1];
  • 2、原本num2的数组元素之和
sum2 = num2[0] + num2[1] + ... + num2[n-2] + num2[n-1];

设选择了替换的子数组端点分别为 left 和 right

  • 3、替换了子数组的num1的数组元素之和
sum1 = num1[0] + num1[1] + ... + num2[left] + ... + num2[right] - num1[left] - ... - num1[right] + ... + num1[n-2] + num1[n-1];
  • 4、替换了子数组的num2的数组元素之和
sum2 = num2[0] + num2[1] + ... + num1[left] + ... + num1[right] - num2[left] - ... - num2[right] + ... + num2[n-2] + num2[n-1];

化简一下替换了子数组的数组元素的求和公式,可以得到:

sum = num2[0] + num2[1] + ... + num2[n-2] + num2[n-1] + num1[left] - num2[left] + num1[left + 1] - num2[left + 1] + ... + num1[right] - num2[right];

sum = sum2 + num1[left] - num2[left] + num1[left + 1] - num2[left + 1] + ... + num1[right] - num2[right];

所以我们可以得到以下公式

sum = i=0n\sum \limits _{i = 0}^nnum2[i] + i=lr\sum \limits _{i = l}^r(num1[i] - num2[i]) i=0n\sum \limits _{i = 0}^nnum2[i]是固定值,所以我们只需要找出i=lr\sum \limits _{i = l}^r(num1[i] - num2[i])的最大值即可。

AC代码

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
 var maximumsSplicedArray = function(nums1, nums2) {
    const getMaxSum = function(nums1,nums2) {
        let s1 = 0, maxSum = 0, s = 0, i = 0;
        while (i < nums1.length) {
            s = Math.max(s + nums2[i] - nums1[i], 0);
            s1 += nums1[i++];
            maxSum = Math.max(maxSum, s);
        }
        return s1 + maxSum;
    }
    return Math.max(getMaxSum(nums1, nums2), getMaxSum(nums2, nums1));
};

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。