Skip to content

K次取反后最大化数组和

题目描述

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

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

题目链接:https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations/

文章讲解:https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations

思考

贪心解法

本题思路应该比较简单,尽可能让小的负数取反,尽可能让小的非负数取反。整体和最大。

首先应该把尽可能小的负数取反,如果所有负数都取反了,还不够k次,那么此时就应该找数值最小的非负整数取反。

又因为可以多次反转同一个索引,所以我们只需要逮着同一个非负整数反转就行。

还有一点需要注意的是,选择非负整数反转的时候不一定选择原生数反转,还有可能选择原来是负数的(但经过反转)的数。

这样达到全局最优。

解题步骤:

  • 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  • 第二步:从前向后遍历,遇到负数将其变为正数,同时K--
  • 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
  • 第四步:求和

代码实现

C++
int largestSumAfterKNegations(vector<int>& A, int K){
    std::sort(A.begin(),A.end(),[](int a,int b){return abs(a) > abs(b);});
    for(int i = 0;i<A.size();i++){
        if(A[i] < 0 && K > 0){
            A[i] *= -1;
            K--;
        }
    }
    if(K % 2 == 1) A[A.size()-1]*=-1;
    int result = 0;
    for(auto a:A){result+=a;}
    return result;
}