题目:
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
class Solution {
/*
两次贪心的思路:
1、数组中有负数出现时:
局部最优:让绝对值最大的负数变为正数,即当前数值达到最大 整体最优:整个数组和达到最大
2、经过1的处理后,仍有负数,且 K 还大于0
局部最优:只找到最小的正整数进行反转,即可使当前的数值达到最大
全局最优:整个数组和达到最大
*/
/****************我还是个小菜鸟,我想只遍历一次,但是我做不到,还是分治思想,一步步来吧***/
// int largestSumAfterKNegations(vector<int>& A, int K)
// {
// sort(A.begin(), A.end());
// int result = 0;
//
// // int zhengshu = INT_MIN; // 记录第一个正数
// // for(int i = 0; i < A.size(); A++)
// // {
// // if(K >= 0)
// // {
// // if(A[i] < 0)
// // {
// // A[i] = -A[i];
// // K--;
// // }
// // // 我想在这里找到第一个非负数,并记录它的下标,但是不知道怎么找,
// // // 因为在for循环中,会不断被更新
// // }
// // result += A[i];
// // }
// }
// 注意哦~ 这里没有加 public 或者private
static bool cmp(int a, int b)
{
return abs(a) > abs(b);
}
public:
int largestSumAfterKNegations(vector<int>& A, int K)
{
// 第一步:将数组按绝对值大小进行排序
sort(A.begin(), A.end(), cmp);
// 第二步:从前向后遍历,将遇到的负数变为正数,同时K--
for(int& it : A)
{
if(it < 0 && K > 0)
{
it *= -1;
K--;
}
}
// 第三步:判断此时 K 是否还大于0,并将K 消耗掉
if(K % 2 != 0)
{
A[A.size() - 1] *= -1;
}
// 第四步:求和
int result = 0;
for(int it : A)
{
result += it;
}
return result;
}
};