【我也想刷穿 LeetCode】1005. K 次取反后最大化的数组和

66 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

现在前端很多岗位面试需要有一定的算法基础,或者说经常刷算法的会优先考虑。

因此每天刷刷LeetCode非常有必要

在这之前我也刷过一些算法题,也希望以后也坚持刷,跟某掘友一样,我也想刷穿 LeetCode

一、题目描述

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

二、思路分析

此处撰写解题思路 这题比较简单,首先计算nums中负数的数量less, 然后拆解开来一共就三种情况

k 比less小,这种情况只需要把负数中的k个最小值翻转一下就可以了

k 比less大,这种情况又分两种

2.1 余数是偶数的情况,证明可以把所有的负数翻转为正数,余数偶数就是再连续翻转两次,值不变,所以计算所有数字的绝对值相加即可

2.2 余数是奇数的情况,这种情况最复杂,前期同 2.1 一样,把所有绝对值加一起,然后需要额外多翻转一次,也就是找到绝对值中最接近 0 的数字,这有两种方法

2.2.1 一是重新把 nums 按照绝对值排序,取 0

2.2.2 二是在2.2 绝对值累加的时候通过增加一个min变量作为中继条件存储我采用的是这种方法

三、代码实现

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var largestSumAfterKNegations = function (nums, k) {
  // 1.异常情况,k = 0的情况,不过按照题目描述可以不需要
  if (k === 0) return nums.reduce((l, i) => l += i, 0)
  // 2.先把数组排个序,方便后续处理 k < less 的翻转
  nums.sort((a, b) => a - b)
  // 3. 计算 <0 的数字的数量
  const less = nums.filter(a => a < 0).length
  if (k < less) {
    // 如果<0 的数字比可以翻转的步数多,同题解1,直接翻转排序后的前 k 个,累加就可以了
    for (let i = 0; i < k; i++) {
      nums[i] = -nums[i]
    }
    return nums.reduce((l, i) => l += i, 0)
  } else {
    // 如果 <0 的比翻转的少, 同题解 2.2 分成两组条件,由于我采用了2.2.2 的方法,可以提前把数字的绝对值累加到一起赋值 t
    let min = 999999
    const t = nums.reduce((l, i) => {
      l += Math.abs(i)
      if (Math.abs(i) < min) {
        min = Math.abs(i)
      }
      return l
    }, 0)
    // 这里是 2.1 的判定条件,如果(k - less) % 2 === 0 也就是把所有的负数翻转成正数之后额外需要翻转偶数次,最终结果还是都是正数,把刚才的绝对值直接返回去就行了
    if ((k - less) % 2 === 0) {
      return t
    } else {
      // 这里是2.2.2 的判定条件,直接减去 2 * min, 因为刚才计算 t 的时候多加了一个 min ,同时 min 应该为负数,所以减去2 min
      return t - 2 * min
    }
  }
};

四、总结

以上就是本道题的所有内容了,本系列会持续更,欢迎点赞、关注、收藏,另外如有其他的问题,欢迎下方留言给我,我会第一时间回复你,感谢~