K次取反后最大的数组和

1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

  • 选择某个下标 i 并将 nums[i] 替换为 -nums[i]

重复这个过程恰好 k 次。可以多次选择同一个下标 i

以这种方式修改数组后,返回数组 可能的最大和

示例 1:

1
2
3
输入:nums = [4,2,3], k = 1
输出:5
解释:选择下标 1 ,nums 变为 [4,-2,3]

示例 2:

1
2
3
输入:nums = [3,-1,0,2], k = 3
输出:6
解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2]

示例 3:

1
2
3
输入:nums = [2,-3,-1,5,-4], k = 2
输出:13
解释:选择下标 (1, 4) ,nums 变为 [2,3,-1,5,4] 。

提示:

  • 1 <= nums.length <= 104
  • -100 <= nums[i] <= 100
  • 1 <= k <= 104
方法一

数组进行排序

k够用:

  • 把所有负数都反转一遍​
  • 再次排序
  • 把最小的数反复反转,用完k

k不够用:

  • 把前面的最前面的数反转直到用完k
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {

Arrays.sort(nums);
for(int i = 0; i < nums.length; i++){
if(nums[i] < 0 && k > 0){
nums[i] *= -1;
k--;
if(k == 0){
break;
}
}
}

Arrays.sort(nums);
if(k % 2 == 1){
nums[0] *= -1;
}

int ans = 0;
for(int x : nums){
ans += x;
}
return ans;
}
}
方法二
  • 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  • 遇到负数将其变为正数,同时K–
  • 如果K还大于0,那么反复绝对值最小的元素,该元素为数组最后一个元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public static int largestSumAfterKNegations(int[] nums, int k) {
nums = Arrays.stream(nums).boxed().
sorted((a,b) -> Math.abs(b) - Math.abs(a)).mapToInt(Integer::intValue).toArray();

for(int i = 0; i < nums.length; i++){
if(nums[i] < 0 && k > 0){
nums[i] *= -1;
k--;
if(k == 0){
break;
}
}
}

if(k % 2 == 1) nums[nums.length - 1] *= -1;

int ans = 0;
for(int x : nums){
ans += x;
}
return ans;
}
}

K次取反后最大的数组和
http://example.com/2023/02/27/算法/贪心/7. K 次取反后最大化的数组和/
作者
PALE13
发布于
2023年2月27日
许可协议