Skip to content

Commit 30a1ef9

Browse files
committed
feat: add maximize sum of array after k negations
1 parent 51f59c6 commit 30a1ef9

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@
7676
"clocale": "cpp",
7777
"fstream": "cpp",
7878
"iomanip": "cpp",
79-
"set": "cpp"
79+
"set": "cpp",
80+
"version": "cpp",
81+
"filesystem": "cpp"
8082
},
8183
"C_Cpp.errorSquiggles": "Disabled",
8284
"fileheader.LastModifiedBy": "Chacha",
Binary file not shown.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* @Author: Chacha
3+
* @Date: 2022-05-17 22:14:56
4+
* @Last Modified by: Chacha
5+
* @Last Modified time: 2022-05-17 22:42:44
6+
*/
7+
8+
/**
9+
* 来源:https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations/
10+
*
11+
* 1005. K 次取反后最大化的数组和
12+
*
13+
* 给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:
14+
* 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
15+
* 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
16+
* 以这种方式修改数组后,返回数组 可能的最大和 。
17+
*
18+
* 示例 1:
19+
* 输入:nums = [4,2,3], k = 1
20+
* 输出:5
21+
* 解释:选择下标 1 ,nums 变为 [4,-2,3] 。
22+
*
23+
* 示例 2:
24+
* 输入:nums = [3,-1,0,2], k = 3
25+
* 输出:6
26+
* 解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2] 。
27+
*
28+
* 示例 3:
29+
* 输入:nums = [2,-3,-1,5,-4], k = 2
30+
* 输出:13
31+
* 解释:选择下标 (1, 4) ,nums 变为 [2,3,-1,5,4] 。
32+
*
33+
*/
34+
#include <iostream>
35+
#include <vector>
36+
37+
using namespace std;
38+
39+
class Solution
40+
{
41+
42+
static bool compare(int a, int b);
43+
44+
private:
45+
/* data */
46+
public:
47+
int largestSumAfterKNegations(vector<int> &nums, int k);
48+
};
49+
50+
bool Solution::compare(int a, int b)
51+
{
52+
return abs(a) > abs(b);
53+
}
54+
55+
/**
56+
* 方法:贪心的思路
57+
*
58+
* 局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。
59+
* 那么如果将负数都转变为正数了,K依然大于0,此时的问题是一个有序正整数序列,如何转变K次正负,让数组和达到最大。
60+
* 那么又是一个贪心:局部最优:只找数值最小的正整数进行反转,当前数值可以达到最大,
61+
* 例如正整数数组{5, 3, 1},反转1 得到-1 比 反转5得到的-5 大多了,全局最优:整个 数组和 达到最大。
62+
*
63+
* 解题步骤:
64+
* 1. 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小。
65+
* 2. 从前向后遍历,遇到负数将其变为正数,同时K--
66+
* 3. 如果K还大于0,那么反复转变数值最小的元素,将K用完
67+
* 4. 求和
68+
*
69+
*/
70+
int Solution::largestSumAfterKNegations(vector<int> &nums, int k)
71+
{
72+
// 按绝对值大小从大到小排序
73+
sort(nums.begin(), nums.end(), compare);
74+
75+
for (int i = 0; i < nums.size(); i++)
76+
{
77+
if (nums[i] < 0 && k > 0)
78+
{
79+
nums[i] *= -1;
80+
k--;
81+
}
82+
}
83+
84+
if (k % 2 == 1)
85+
{
86+
nums[nums.size() - 1] *= -1;
87+
}
88+
89+
int result = 0;
90+
for (int n : nums)
91+
result += n; // 第四步
92+
93+
return result;
94+
}
95+
96+
int main(int argc, char const *argv[])
97+
{
98+
Solution s;
99+
vector<int> nums = {4, 2, 3};
100+
vector<int> nums1 = {3, -1, 0, 2};
101+
vector<int> nums2 = {2, -3, -1, 5, -4};
102+
103+
cout << "nums = [4, 2, 3], k = 1, 最大和: " << s.largestSumAfterKNegations(nums, 1) << endl;
104+
cout << "nums = [3,-1,0,2], k = 3, 最大和: " << s.largestSumAfterKNegations(nums1, 3) << endl;
105+
cout << "nums = [2,-3,-1,5,-4], k = 2, 最大和: " << s.largestSumAfterKNegations(nums2, 2) << endl;
106+
107+
return 0;
108+
}

0 commit comments

Comments
 (0)