一、题目
LeetCode-1005. K 次取反后最大化的数组和
地址:https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/
难度:简单
给定一个整数数组 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 <= 10000
1 <= K <= 10000
-100 <= A[i] <= 100
二、解题思路
尽可能的把负数变成正数,尽可能的把最小的正数变为负数,这样数组的和最大。
那么代码如何实现呢?先对数组排序,把负数都变为正数(操作次数小于k)。再次排序,判断剩下k次奇偶性,如果是偶数,--得正;如果是正数把nums[0](当前最小值)取反。
最后,计算数组和即可。
三、实现过程
c++
class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
int i = 0;
while(k > 0 && nums[i] < 0){
nums[i] = -nums[i];
i++;
k--;
}
sort(nums.begin(),nums.end());
k = k % 2;
if(k == 1){
nums[0] *= -1;
}
int sum = 0;
for(int i = 0; i < nums.size();++i){
sum += nums[i];
}
return sum;
}
};
PHP
class Solution {
/**
* @param Integer[] $nums
* @param Integer $k
* @return Integer
*/
function largestSumAfterKNegations($nums, $k) {
sort($nums);
$i = 0;
while($k > 0 && $nums[$i] < 0){
$nums[$i] = -$nums[$i];
$i++;
$k--;
}
sort($nums);
$k = $k % 2;
if($k == 1){
$nums[0] = -$nums[0];
}
return array_sum($nums);
}
}
JavaScript
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var largestSumAfterKNegations = function(nums, k) {
nums.sort((a,b)=>a-b);
let i = 0;
while(k > 0 && nums[i] < 0){
nums[i] = -nums[i];
i++;
k--;
}
nums.sort((a,b)=>a-b);
k = k % 2;
if(k == 1){
nums[0] = -nums[0];
}
let sum = 0;
for(let i = 0;i < nums.length; ++i){
sum += nums[i];
}
return sum;
};
四、小结
本题的特点在于使用了两次贪心策略。
第一次,让绝对值大的负数变为正数。
如果将负数都转变为正数了,K依然大于0,如何转变K次正负,让数组和达到最大。
第二次,只要找到数值最小的正整数进行反转即可。
网友评论