持续创作,加速成长!这是我参与「掘金日新计划 · 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 = 1 和 right = 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 = 3 和 right = 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
思路分析
首先我们要先理解题意,题目的意思是会给我们两个数组,我们需要找到两个端点left和right,交换 两个子数组 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 = num2[i] + (num1[i] - num2[i]) num2[i]是固定值,所以我们只需要找出(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前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。