/*** @param {number[]} nums* @param {number} k* @return {number}*/const numsToNumber = (nums) => {if (nums.length === 0) {return 0;}return nums.reduce((prev, next) => {return prev + next;});};var largestSumAfterKNegations = function (nums, k) {if (nums.length === 0) {return 0;}nums.sort((prev, next) => {return prev - next;});const l1 = nums.filter((num) => { return num < 0 }).sort((prev, next) => {return prev - next;});const t = k % 2 === 0;// 考虑无复数的情况if (l1.length === 0 && t) {return numsToNumber(nums);} else if (l1.length === 0 && !t) {return numsToNumber(nums) - 2 * nums[0];}// 到这里开始考虑数组内有负数的情况const t2 = (k - l1.length) <= 0; //考虑k与负数个数的关系if (t2) {return numsToNumber(nums.filter((num) => { return num >= 0 })) - numsToNumber(l1.slice(0, k)) + numsToNumber(l1.slice(k, l1.length));}const t3 = (k - l1.length) % 2 === 0; //k > l1.length// t3if (t3) {return numsToNumber(nums.map((num) => { return Math.abs(num) }));}const l2 = nums.map((num) => { return Math.abs(num) }).sort((prev, next) => {return prev - next;});return numsToNumber(l2) - 2 * l2[0];};
思路:贪心算法
- 首先判断nums内有无负数(利用 l1 的长度来计算)以及k的奇偶性

- l1.length===0的情况下,如果k为偶数则自我抵消,对原数组无任何影响;若k为奇数则需要令nums的和减去两倍的nums中的最小值:

- 当l1.length>0时,我们首先考虑l1.length与k的差值大于等于0的特殊情况


- 接下来讨论l1.length < k的情况,此时如果(l1.length-k)%2===0,则k可以将l1中的负数全部取反,由于还会剩下偶数次取反的机会可以自我抵消(负负得正),因此我们只需要将nums全部取绝对值相加即可

- 若l1.length < k且(l1.length-k)%2!==0,则首先:

由上可知l2是nums经过取绝对值并排序过后的数组,在这种情况下由于我们必须做出“牺牲”,令l2之中最小的值消耗完取反次数,则此时这个最小值会为负数,我们需要的结果就是l2的总和减去2倍的该最小值:
ps.本人水平有限,欢迎批评指正

