方法一 个人方法:
?将数组从小到大排序后,假设数组共有n个负数,要使数组的和尽可能大就要尽可能将较大的负数变为正数,有以下几种情况:
1、k<=n,那就把数组前k个负数都转为正数即可。
2、k>n,把所有n都翻转为正数,看负数里最小的数和正数里最小的数谁绝对值更小,剩下的次数都用来翻转这个数。
3、n=0,即数组里都是正数,那么k次都翻转最下的那个数。
var largestSumAfterKNegations = function(nums, k) {
nums= nums.sort((a,b)=>a-b)
var i=0
while(k--){
if(nums[i]<0){
nums[i]=-nums[i]
if(nums[i+1]<=0 || nums[i+1]<nums[i]){
i++
}
}else{
nums[i]=-nums[i]
}
}
return nums.reduce((a,b)=>a+b,0)
};
消耗时间和内存情况:
方法二(方法一优化版):
数组排序不一定要把正负数分开,也可以直接按照绝对值从大到小排序,那么循环数组时先碰到的负数一定是绝对值较大的,需要优先翻转,具体思路如下:
1、将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
2、从前向后遍历,遇到负数将其变为正数,同时K--
3、如果K还大于0,那么反复转变数值最小的元素,将K用完
4、求和
var largestSumAfterKNegations = function(nums, k) {
nums.sort((a,b) => Math.abs(b) - Math.abs(a))
for(let i = 0 ;i < nums.length; i++){
if(nums[i] < 0 && k > 0){
nums[i] = - nums[i];
k--;
}
}
while( k > 0 ){
nums[nums.length-1] = - nums[nums.length-1]
k--;
}
return nums.reduce((a, b) => a+b,0)
};
消耗时间和内存情况: