给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:
- 选择某个下标
i并将nums[i]替换为-nums[i]。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
以这种方式修改数组后,返回数组 可能的最大和 。
示例 1:
输入: nums = [4,2,3], k = 1
输出: 5
解释: 选择下标 1 ,nums 变为 [4,-2,3] 。
示例 2:
输入: nums = [3,-1,0,2], k = 3
输出: 6
解释: 选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2] 。
示例 3:
输入: nums = [2,-3,-1,5,-4], k = 2
输出: 13
解释: 选择下标 (1, 4) ,nums 变为 [2,3,-1,5,4] 。
题解: 贪心的思路,
局部最优:让绝对值大的负数变为正数,当前数值达到最大,
整体最优:整个数组和达到最大。
局部最优可以推出全局最优。
那么如果将负数都转变为正数了,K依然大于0,此时的问题是一个有序正整数序列, 如何转变K次正负,让 数组和 达到最大
那么本题的解题步骤为:
第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
第二步:从前向后遍历,遇到负数将其变为正数,同时K--
第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
第四步:求和
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var largestSumAfterKNegations = function (nums, k) {
// 根据绝对值进行倒序 排序
nums.sort((a, b) => {
return Math.abs(b) - Math.abs(a)
})
// 遍历数组当遇到负数且k大于0时当前数值由负变正k --
for (let i = 0; i < nums.length; i++) {
if (nums[i] < 0 && k > 0) {
nums[i] *= -1
k--
}
}
// 当还存在k 且k为奇数时
if (k > 0 && k % 2 === 1) {
nums[nums.length - 1] *= -1
}
k = 0
// 累加
return nums.reduce((a, b) => {
return a + b
})
};
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。