int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
while (k != 0) {
if(nums[0] < 0) {
nums[0] = -nums[0];
k--;
sort(nums.begin(),nums.end());
} else {
nums[0] = -nums[0];
k--;
}
}
int sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
}
return sum;
}
这是我自己写的代码。每转换一次就sort一次。保持数组最左边一定是整个数组的最小值,这样如果最小值小于0,就换,如果最小值不小于0了。那么也换最小值,因为只有换最小值才能醉倒对整个数组之和影响最小。但是这太慢了,因为要sort很多次。
static bool cmp(int a, int b) {
return abs(a) > abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end(),cmp);
for (int i = 0; i < nums.size(); ++i) {
if(k > 0 && nums[i] < 0) {
nums[i] = -nums[i];
k--;
}
}
if(k % 2 == 1) {
nums[nums.size() - 1] *= -1;
}
int sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
}
return sum;
}
这是代码随想录的代码。思想也很简单。绝对值从大到小排序数组,然后小于0的从左到右依次取反。遍历完一遍发现k还没用完,说明小于0的已经全部变成正数了。这个时候整个数组就是非负数组,最小值也就是最后一个元素。也就是说将剩余的k次全作用在最后一个元素就行了。正常想法就是将最后一个元素取反k次。但是如果利用k的奇偶性会更好。k%2 == 1,说明取反一次即可, ==0就不用取反。多方便!这个思维虽然知道了很简单,但是轮到自己凭空想,我是第一反应肯定想不到用k的奇偶性,只会觉得取反k次即可,多简单,就写上去了。并不会思考如何优化。所以从这一点应该意识到,数学思维非常重要,头脑多转一个弯,就会省去很多时间和精力!