题目:
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
示例:
输入:A = [3,-1,0,2], K = 3
输出:6
解释:选择索引 (1, 2, 2) ,然后 A 变为 [3,1,0,2]。
解题方法:
一开始我想通过判断负数数量和K的关系分情况讨论,后来觉得有点麻烦,手上没有纸笔。看了很多题解以后,找到了自认为逻辑上比较清晰的方法:
- 首先进行排序,没有办法避免,需要按照数字大小对负数进行符号反转;
- 遍历数组,将数组中的负数进行反转,如果K自减到0或者没有负数了,就停止遍历。
- 累加数组,获得临时的累加和;
- 最后就是判断K值。先看现在K的情况:K可能为0,那么上面的临时累加和就是最终累加和
;K不为0,说明负数已经全部反转了,没有负数了,现在需要找到最小的数,且这个数需要进行K次反转,如果K是偶数,连续两次反转就是原值,那么累加和不变,如果K是奇数,那么就需要用临时累加和减去两倍的最小值,因为临时累加和中包含了一个最小值,反转后还要再减去一个,所以是两倍。
总的来说,这个程序的逻辑还是很清晰易懂的,结果也还可以,就是占用内存有点多。
代码和结果:
class Solution {
public:
int largestSumAfterKNegations(vector<int>& A, int K) {
sort(A.begin(),A.end());
int i;
for(i=0;i<A.size();i++)
{
if(K==0)
break;
else if(A[i]<0)
{
A[i]=-A[i];
K--;
}
else
break;
}
int smv=0;
for(i=0;i<A.size();i++)
{
smv+=A[i];
}
if(K%2==0)
return smv;
int miv=*min_element(A.begin(),A.end());
return smv-2*miv;
}
};
运行结果:原题链接:https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/