1005. K 次取反后最大化的数组和

72 阅读2分钟

给你一个整数数组 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)

链接:leetcode.cn/problems/ma…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。