leetcode 1005 K 次取反后最大化的数组和
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引
i并将A[i]替换为-A[i],然后总共重复这个过程K次。(我们可以多次选择同一个索引i。)以这种方式修改数组后,返回数组可能的最大和。
示例 1:
输入:A = [4,2,3], K = 1 输出:5 解释:选择索引 (1,) ,然后 A 变为 [4,-2,3]。示例 2:
输入:A = [3,-1,0,2], K = 3 输出:6 解释:选择索引 (1, 2, 2) ,然后 A 变为 [3,1,0,2]。示例 3:
输入:A = [2,-3,-1,5,-4], K = 2 输出:13 解释:选择索引 (1, 4) ,然后 A 变为 [2,3,-1,5,4]。
提示:
1 <= A.length <= 100001 <= K <= 10000-100 <= A[i] <= 100
先将数组排序,在负数里面尽可能多的取反,如果取反的元素个数达到了k,我们直接返回累计和,如果没达到k,也就是说负数没那么多,这时数组里都是>=0的数了。我们还有x个取反的机会没用,这时候取反会使得数组和变小,所以我们只对最小的元素下手,如果x为偶数,那结果不变,我们忽略,如果为奇数,我们对最小元素取反。
class Solution {
public:
int largestSumAfterKNegations(vector<int>& A, int k) {
sort(A.begin(),A.end());
int i=0;
while(i<k&&A[i]<0) A[i++]*=-1;
sort(A.begin(),A.end());
if(k>i&&(k-i)%2==1)A[0]*=-1;
return accumulate(A.begin(),A.end(),0);
}
};
第一次代码,略显粗糙,思路差不多,k小于负数的个数,全部翻过来求和;否则,看还剩多少次机会,剩余偶数次略过,剩余奇数次,找到最小的翻过来。
class Solution {
public:
int largestSumAfterKNegations(vector<int>& A, int k) {
sort(A.begin(),A.end());
int f=fuNum(A);
if(k<=f){
int res=0;
int n=A.size();
for(int i=0;i<n;i++){
if(i<k)res+=-A[i];
else res+=A[i];
}
return res;
}
else{
int t=k-f;
int res=0;
int minv=INT_MAX;
for(int a:A){
res+=abs(a);
minv=min(minv,abs(a));
}
if(t%2!=0){
res-=2*minv;
}
return res;
}
}
int fuNum(vector<int>& A){
int res=0;
for(int a:A){
if(a<0)res++;
}
return res;
}
};
参考:

浙公网安备 33010602011771号