题目
思路
我自己的思路是先对这个序列进行排序,然后优先将负数取反。对于将所有负数都取反了k仍然有次数可以对k的奇偶性进行讨论,如果是奇数,我们找出序列中最小的数进行取反。
优化的思路是利用哈希表进行正负数计数,因为题中的范围是-100~100.采用空间换时间。
代码
class Solution {
private:
int getval(vector<int> s){
int res=0,len=s.size();
for(int i=0;i<len;++i){
res+=s[i];
}
return res;
}
int getMinPos(vector<int> s){
int index=0,min_=INT_MAX,len=s.size();
for(int i=0;i<len;++i){
if(s[i]<min_){
min_=s[i];
index=i;
}
}
return index;
}
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
int len=nums.size();
for(int i=0;i<len;++i){
if(k==0) return getval(nums);
else{
if(nums[i]<=0) {
nums[i]=-nums[i];
k--;
}else break;
}
}
if(k%2==0) return getval(nums);
else{
//如果是奇数,我们找出序列中最小的数进行取反
int index=getMinPos(nums);
nums[index]=-nums[index];
return getval(nums);
}
}
};
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
unordered_map<int,int> m;
int len=nums.size();
for(int i=0;i<len;++i){
m[nums[i]]++;//利用哈希表来统计对应数的个数
}
int res=accumulate(nums.begin(),nums.end(),0);
//学习到了一个关键字 accumualte
//优先对负数进行处理
for(int i=-100;i<0;++i){
if(k==0) break;
if(m[i]){
//如果这个负数存在
int temp=min(k,m[i]);//找出较小的那个
k-=temp;
res+=-2*temp*i;//那么结果需要加这么多
m[-i]=temp;
//注意这个细节就是 负数转过去后应该变成正数
}
}
//把所有的负数都处理完毕了
//注意0这个点 如果有0的话就不用管它了 直接对0操作即可
if(k%2!=0&&!m[0]){
for(int i=1;i<=100;++i){
if(m[i]){
res-=2*i;
break;
}
}
}
return res;
}
};
后记
但的确是前面一个跑的更快啊