联系我
×

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

查看原题

解题思路

主要思想就是尽量多的把负数变为正数,负数不够变化时,变化最小的正数。

  1. 先将数组排序,便于后续操作数组中的数据
  2. 找出数组中负数的个数,记录到count中,并且计算原来数组的和记录到sum中
  3. 开始判断变化的次数和负数个数的关系
    • 如果变化的次数小于等于负数的个数,k<=count,则直接找出最小的k个负数,最大和为sum + k个负数绝对值的二倍
    • 如果变化的次数大于负数的个数,继续判断负数的个数是否为0
      1. 为0,则判断k是否为偶数,如果为偶数则直接返回sum,如果为奇数,则直接返回sum - 二倍的nums[0]
      2. 不为0,先求出将负数全变为正数的最大值,然后求出变化次数和负数个数的差值temp,继续判断temp是奇数还是偶数
        • temp为偶数,直接返回最大值
        • temp为奇数,继续判断数组是否为全负数,如果是全负数 return maxSum + 2(nums[nums.length-1]),如果不是则 return maxSum - 2Math.min(Math.abs(nums[count-1]),Math.abs(nums[count]))。

代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
// 统计负数的个数
var largestSumAfterKNegations = function(nums, k) {
	let count = 0;//负数的个数
	let maxSum = 0;//可能的最大和
	let sum = 0;//原来的
	nums.sort((a,b)=>a-b);
	nums.forEach(item=>{
		if(item < 0){
			count ++;
		}
		sum += item;
	})
	if(k<=count){
		maxSum = sum;
		for(let i =0;i<k;i++){
			maxSum+=(-nums[i]*2);
		}
		return maxSum;
	}else if(k>count){
		if(!count){
			if(k%2===0){
				return sum;
			}else{
				return sum-2*nums[0];
			}
		}else{
			let temp  = k-count;
			maxSum = sum;
			for(let i =0;i<count;i++){
				maxSum+=(-nums[i]*2);
			}
			if(temp%2===0){
				return maxSum;
			}else{
				if(count === nums.length){
					return maxSum + 2*(nums[nums.length-1])
				}else{
					return maxSum - 2*Math.min(Math.abs(nums[count-1]),Math.abs(nums[count]))
				}
			}
		}
	}
};
posted @ 2021-12-23 16:38  .筱  阅读(41)  评论(0)    收藏  举报