给你一个整数数组 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] 。
1.贪心算法:
①如果存在负数,每次将最小的负数取反,这样数值总和时在增大的;
②如果负数全部取完后,还有剩余次数:
如果存在0,那么只要一直取0就行;
如果次数为偶数次,那就全部改任意一个数字
如果次数为奇数次,那就把剩的那一次留给最小的正数,减少总和的损失。
从上述规律看出来,选择优先队列,每次都取最小值进行取反即可。
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){//优先队列,定义排序标准
public int compare(Integer val1,Integer val2){
return val1 - val2;
}
});
for(int i = 0;i < nums.length;i++){//把数组中的每个元素加入优先队列
pq.offer(nums[i]);
}
for(int i = 0;i < k;i++){//每次取出最小的数,取反后重新加入优先队列
int temp = pq.poll();
pq.offer(-temp);
}
int maxSum = 0;
while(!pq.isEmpty()){//依次取出优先队列中的值求和
int num = pq.poll();
maxSum += num;
}
return maxSum;
}
}
来自评论@绝望者x,利用快排来排序。
快速排序思想参考:快速排序 - 如果天空不死 - 博客园
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
// 尝试排序后再考虑
// 首先k如果大于nums.length, 那么相当于可以让所有值变为正数, 同时对最小的值不断变换正负
quickSort(nums, 0, nums.length - 1);
int i = 0;
while (i < nums.length) {
if (nums[i] >= 0 || k-- == 0) {
break;
}
// 对负数取反
nums[i] = -nums[i++];
}
if (k > 0 && (k & 1) != 0) {
// 说明还能继续取反, 于是对最小值不断取反
if (i == nums.length || i > 0 && nums[i] > nums[i - 1]) {
i--;
}
nums[i] = -nums[i];
}
// 求和
i = 0;
int sum = 0;
while (i < nums.length) {
sum += nums[i++];
}
return sum;
}
private void quickSort(int[] nums, int left, int right) {
if (left < right) {
int lt = left - 1;
int rt = right + 1;
int curIndex = left;
int curValue = nums[curIndex];
int temp;
while (curIndex < rt) {
if (curValue > nums[curIndex]) {
temp = nums[++lt];
nums[lt] = nums[curIndex];
nums[curIndex++] = temp;
} else if (curValue < nums[curIndex]) {
temp = nums[--rt];
nums[rt] = nums[curIndex];
nums[curIndex] = temp;
} else {
curIndex++;
}
}
quickSort(nums, left, lt);
quickSort(nums, rt, right);
}
}
}
题源:力扣