1 两次贪心
考虑到这几种情况
1.1 K <= A.size()
-
+
+
+
+
+
K
+
+++++K+
+++++K+,第一个元素按
K % 2
正负加和,其他累加即可 -
−
−
−
−
−
K
−
-----K-
−−−−−K−, 在
[0, K - 1]
全部取负加和,其他累加即可 -
−
−
K
−
+
+
+
--K-+++
−−K−+++,当
K < =负数个数
按第二步做 -
−
−
−
−
+
K
+
+
----+K++
−−−−+K++,当
K > 负数个数
,负数个数取负加和,正数按第一步做
1.2 K > A.size()
- + + + + + + + +++++++ +++++++,同上步第一条
-
−
−
−
−
−
−
−
-------
−−−−−−−,第一个元素按
K % 2
正负加和,其他取负
累加 -
−
−
K
−
+
+
+
--K-+++
−−K−+++,负数部分取正累加并
追踪最小绝对值
,到第一个正数时对比,①若前者小,且剩下的K会落单,则减去2倍最小值并加上当前正数,之后累加;②若后者小,且剩下的K会落单,则该正数按K % 2
正负加和,其他累加 - − − − − + K + + ----+K++ −−−−+K++,同上步第四条
但其实按绝对值从大到小排序,就可以仅用少量的判断实现上述情况,具体代码如下
class Solution {
private:
static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
public:
int largestSumAfterKNegations(vector<int>& A, int K) {
// 1.按绝对值从大到小排列
sort(A.begin(), A.end(), cmp);
int sum = 0;
for (auto& num : A) {
// 2.负值变正
if (num < 0 && K > 0) {
num *= -1;
K--;
}
sum += num;
}
// 3.处理K > A.size()情况
if (K > 0 && K % 2 == 1) sum -= 2 * A[A.size() - 1];
return sum;
}
};