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

本文最后更新于:2021年2月24日 下午

给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)

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

示例 1:

1
2
3
输入:A = [4,2,3], K = 1
输出:5
解释:选择索引 (1,) ,然后 A 变为 [4,-2,3]。

示例 2:

1
2
3
输入:A = [3,-1,0,2], K = 3
输出:6
解释:选择索引 (1, 2, 2) ,然后 A 变为 [3,1,0,2]。

示例 3:

1
2
3
输入:A = [2,-3,-1,5,-4], K = 2
输出:13
解释:选择索引 (1, 4) ,然后 A 变为 [2,3,-1,5,4]。

提示:

  1. 1 <= A.length <= 10000
  2. 1 <= K <= 10000
  3. -100 <= A[i] <= 100

Solution

参考 代码随想录

  • 贪心算法
  • 局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个 数组和 达到最大。(第一步、第二步)
  • 局部最优:只找数值最小的正整数进行反转,当前数值可以达到最大,全局最优:整个 数组和 达到最大。(第三步)

本题的解题步骤为:

  • 第一步:将数组按照绝对值大小从大到小排序,「注意要按照绝对值的大小」
  • 第二步:从前向后遍历,遇到负数将其变为正数,同时K–
  • 第三步:如果K还大于0,那么反复转变数值最小的元素,将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
27
28
// @lc code=start
class Solution {
public:
int largestSumAfterKNegations(vector<int>& A, int K) {
sort(A.begin(), A.end(), cmp);
int n = A.size();
for (int i = 0; i < n; ++i) {
if (A[i] < 0 && K > 0) {
A[i] *= -1;
K--;
}
}

while (K) {
A[n-1] *= -1;
K--;
}

int res = 0;
for (int a : A) res += a;
return res;
}

static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
};
// @lc code=end

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!