Skip to content

Commit 4bdd08f

Browse files
committed
feat: update solutions to lc problem: No.1005
No.1005.Maximize Sum Of Array After K Negations
1 parent d98c62a commit 4bdd08f

File tree

6 files changed

+219
-207
lines changed

6 files changed

+219
-207
lines changed

solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README.md

+81-69
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:贪心 + 计数**
60+
61+
我们观察发现,要使得数组的和尽可能大,就应该尽可能地将数组中的最小负数变成正数。
62+
63+
而题目中元素的范围为 $[-100,100]$,因此,我们可以先用哈希表 $cnt$ 统计数组 $nums$ 中每个元素出现的次数。接着从 $-100$ 开始遍历 $x$,如果哈希表中存在 $x$,那么我们取 $m = \min(cnt[x], k)$ 作为元素 $x$ 取反的个数,然后我们将 $cnt[x]$ 减去 $m$,将 $cnt[-x]$ 加上 $m$,并将 $k$ 减去 $m$。如果 $k$ 为 $0$,说明操作已经结束,直接退出循环即可。
64+
65+
如果 $k$ 仍然为奇数,且 $cnt[0]=0$,那么我们还需要取 $cnt$ 中最小的一个正数 $x$,将 $cnt[x]$ 减去 $1$,将 $cnt[-x]$ 加上 $1$。
66+
67+
最后,我们遍历哈希表 $cnt$,将 $x$ 与 $cnt[x]$ 相乘的结果累加,即为答案。
68+
69+
时间复杂度 $O(n + M)$,空间复杂度 $O(M)$。其中 $n$ 和 $M$ 分别为数组 $nums$ 的长度和 $nums$ 的数据范围大小。
70+
5971
<!-- tabs:start -->
6072

6173
### **Python3**
@@ -65,23 +77,22 @@
6577
```python
6678
class Solution:
6779
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
68-
counter = Counter(nums)
69-
ans = sum(nums)
70-
for i in range(-100, 0):
71-
if counter[i]:
72-
ops = min(counter[i], k)
73-
ans -= i * ops * 2
74-
counter[i] -= ops
75-
counter[-i] += ops
76-
k -= ops
80+
cnt = Counter(nums)
81+
for x in range(-100, 0):
82+
if cnt[x]:
83+
m = min(cnt[x], k)
84+
cnt[x] -= m
85+
cnt[-x] += m
86+
k -= m
7787
if k == 0:
7888
break
79-
if k > 0 and k % 2 == 1 and not counter[0]:
80-
for i in range(1, 101):
81-
if counter[i]:
82-
ans -= 2 * i
89+
if k & 1 and cnt[0] == 0:
90+
for x in range(1, 101):
91+
if cnt[x]:
92+
cnt[x] -= 1
93+
cnt[-x] += 1
8394
break
84-
return ans
95+
return sum(x * v for x, v in cnt.items())
8596
```
8697

8798
### **Java**
@@ -91,32 +102,31 @@ class Solution:
91102
```java
92103
class Solution {
93104
public int largestSumAfterKNegations(int[] nums, int k) {
94-
int ans = 0;
95-
Map<Integer, Integer> counter = new HashMap<>();
96-
for (int num : nums) {
97-
ans += num;
98-
counter.put(num, counter.getOrDefault(num, 0) + 1);
105+
Map<Integer, Integer> cnt = new HashMap<>();
106+
for (int x : nums) {
107+
cnt.merge(x, 1, Integer::sum);
99108
}
100-
for (int i = -100; i < 0; ++i) {
101-
if (counter.getOrDefault(i, 0) > 0) {
102-
int ops = Math.min(counter.get(i), k);
103-
ans -= (i * ops * 2);
104-
counter.put(i, counter.getOrDefault(i, 0) - ops);
105-
counter.put(-i, counter.getOrDefault(-i, 0) + ops);
106-
k -= ops;
107-
if (k == 0) {
108-
break;
109-
}
109+
for (int x = -100; x < 0 && k > 0; ++x) {
110+
if (cnt.getOrDefault(x, 0) > 0) {
111+
int m = Math.min(cnt.get(x), k);
112+
cnt.merge(x, -m, Integer::sum);
113+
cnt.merge(-x, m, Integer::sum);
114+
k -= m;
110115
}
111116
}
112-
if (k > 0 && (k % 2) == 1 && counter.get(0) == null) {
113-
for (int i = 1; i < 101; ++i) {
114-
if (counter.getOrDefault(i, 0) > 0) {
115-
ans -= 2 * i;
117+
if ((k & 1) == 1 && cnt.getOrDefault(0, 0) == 0) {
118+
for (int x = 1; x <= 100; ++x) {
119+
if (cnt.getOrDefault(x, 0) > 0) {
120+
cnt.merge(x, -1, Integer::sum);
121+
cnt.merge(-x, 1, Integer::sum);
116122
break;
117123
}
118124
}
119125
}
126+
int ans = 0;
127+
for (var e : cnt.entrySet()) {
128+
ans += e.getKey() * e.getValue();
129+
}
120130
return ans;
121131
}
122132
}
@@ -128,27 +138,31 @@ class Solution {
128138
class Solution {
129139
public:
130140
int largestSumAfterKNegations(vector<int>& nums, int k) {
131-
unordered_map<int, int> counter;
132-
for (int num : nums) ++counter[num];
133-
int ans = accumulate(nums.begin(), nums.end(), 0);
134-
for (int i = -100; i < 0; ++i) {
135-
if (counter[i]) {
136-
int ops = min(counter[i], k);
137-
ans -= (i * ops * 2);
138-
counter[i] -= ops;
139-
counter[-i] += ops;
140-
k -= ops;
141-
if (k == 0) break;
141+
unordered_map<int, int> cnt;
142+
for (int& x : nums) {
143+
++cnt[x];
144+
}
145+
for (int x = -100; x < 0 && k > 0; ++x) {
146+
if (cnt[x]) {
147+
int m = min(cnt[x], k);
148+
cnt[x] -= m;
149+
cnt[-x] += m;
150+
k -= m;
142151
}
143152
}
144-
if (k > 0 && k % 2 == 1 && !counter[0]) {
145-
for (int i = 1; i < 101; ++i) {
146-
if (counter[i]) {
147-
ans -= 2 * i;
153+
if ((k & 1) && !cnt[0]) {
154+
for (int x = 1; x <= 100; ++x) {
155+
if (cnt[x]) {
156+
--cnt[x];
157+
++cnt[-x];
148158
break;
149159
}
150160
}
151161
}
162+
int ans = 0;
163+
for (auto& [x, v] : cnt) {
164+
ans += x * v;
165+
}
152166
return ans;
153167
}
154168
};
@@ -157,34 +171,32 @@ public:
157171
### **Go**
158172
159173
```cpp
160-
func largestSumAfterKNegations(nums []int, k int) int {
161-
ans := 0
162-
counter := make(map[int]int)
163-
for _, num := range nums {
164-
ans += num
165-
counter[num]++
174+
func largestSumAfterKNegations(nums []int, k int) (ans int) {
175+
cnt := map[int]int{}
176+
for _, x := range nums {
177+
cnt[x]++
166178
}
167-
for i := -100; i < 0; i++ {
168-
if counter[i] > 0 {
169-
ops := min(counter[i], k)
170-
ans -= (i * ops * 2)
171-
counter[i] -= ops
172-
counter[-i] += ops
173-
k -= ops
174-
if k == 0 {
175-
break
176-
}
179+
for x := -100; x < 0 && k > 0; x++ {
180+
if cnt[x] > 0 {
181+
m := min(k, cnt[x])
182+
cnt[x] -= m
183+
cnt[-x] += m
184+
k -= m
177185
}
178186
}
179-
if k > 0 && k%2 == 1 && counter[0] == 0 {
180-
for i := 1; i < 101; i++ {
181-
if counter[i] > 0 {
182-
ans -= 2 * i
187+
if k&1 == 1 && cnt[0] == 0 {
188+
for x := 1; x <= 100; x++ {
189+
if cnt[x] > 0 {
190+
cnt[x]--
191+
cnt[-x]++
183192
break
184193
}
185194
}
186195
}
187-
return ans
196+
for x, v := range cnt {
197+
ans += x * v
198+
}
199+
return
188200
}
189201
190202
func min(a, b int) int {

solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README_EN.md

+69-69
Original file line numberDiff line numberDiff line change
@@ -57,56 +57,54 @@
5757
```python
5858
class Solution:
5959
def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
60-
counter = Counter(nums)
61-
ans = sum(nums)
62-
for i in range(-100, 0):
63-
if counter[i]:
64-
ops = min(counter[i], k)
65-
ans -= i * ops * 2
66-
counter[i] -= ops
67-
counter[-i] += ops
68-
k -= ops
60+
cnt = Counter(nums)
61+
for x in range(-100, 0):
62+
if cnt[x]:
63+
m = min(cnt[x], k)
64+
cnt[x] -= m
65+
cnt[-x] += m
66+
k -= m
6967
if k == 0:
7068
break
71-
if k > 0 and k % 2 == 1 and not counter[0]:
72-
for i in range(1, 101):
73-
if counter[i]:
74-
ans -= 2 * i
69+
if k & 1 and cnt[0] == 0:
70+
for x in range(1, 101):
71+
if cnt[x]:
72+
cnt[x] -= 1
73+
cnt[-x] += 1
7574
break
76-
return ans
75+
return sum(x * v for x, v in cnt.items())
7776
```
7877

7978
### **Java**
8079

8180
```java
8281
class Solution {
8382
public int largestSumAfterKNegations(int[] nums, int k) {
84-
int ans = 0;
85-
Map<Integer, Integer> counter = new HashMap<>();
86-
for (int num : nums) {
87-
ans += num;
88-
counter.put(num, counter.getOrDefault(num, 0) + 1);
83+
Map<Integer, Integer> cnt = new HashMap<>();
84+
for (int x : nums) {
85+
cnt.merge(x, 1, Integer::sum);
8986
}
90-
for (int i = -100; i < 0; ++i) {
91-
if (counter.getOrDefault(i, 0) > 0) {
92-
int ops = Math.min(counter.get(i), k);
93-
ans -= (i * ops * 2);
94-
counter.put(i, counter.getOrDefault(i, 0) - ops);
95-
counter.put(-i, counter.getOrDefault(-i, 0) + ops);
96-
k -= ops;
97-
if (k == 0) {
98-
break;
99-
}
87+
for (int x = -100; x < 0 && k > 0; ++x) {
88+
if (cnt.getOrDefault(x, 0) > 0) {
89+
int m = Math.min(cnt.get(x), k);
90+
cnt.merge(x, -m, Integer::sum);
91+
cnt.merge(-x, m, Integer::sum);
92+
k -= m;
10093
}
10194
}
102-
if (k > 0 && (k % 2) == 1 && counter.get(0) == null) {
103-
for (int i = 1; i < 101; ++i) {
104-
if (counter.getOrDefault(i, 0) > 0) {
105-
ans -= 2 * i;
95+
if ((k & 1) == 1 && cnt.getOrDefault(0, 0) == 0) {
96+
for (int x = 1; x <= 100; ++x) {
97+
if (cnt.getOrDefault(x, 0) > 0) {
98+
cnt.merge(x, -1, Integer::sum);
99+
cnt.merge(-x, 1, Integer::sum);
106100
break;
107101
}
108102
}
109103
}
104+
int ans = 0;
105+
for (var e : cnt.entrySet()) {
106+
ans += e.getKey() * e.getValue();
107+
}
110108
return ans;
111109
}
112110
}
@@ -118,27 +116,31 @@ class Solution {
118116
class Solution {
119117
public:
120118
int largestSumAfterKNegations(vector<int>& nums, int k) {
121-
unordered_map<int, int> counter;
122-
for (int num : nums) ++counter[num];
123-
int ans = accumulate(nums.begin(), nums.end(), 0);
124-
for (int i = -100; i < 0; ++i) {
125-
if (counter[i]) {
126-
int ops = min(counter[i], k);
127-
ans -= (i * ops * 2);
128-
counter[i] -= ops;
129-
counter[-i] += ops;
130-
k -= ops;
131-
if (k == 0) break;
119+
unordered_map<int, int> cnt;
120+
for (int& x : nums) {
121+
++cnt[x];
122+
}
123+
for (int x = -100; x < 0 && k > 0; ++x) {
124+
if (cnt[x]) {
125+
int m = min(cnt[x], k);
126+
cnt[x] -= m;
127+
cnt[-x] += m;
128+
k -= m;
132129
}
133130
}
134-
if (k > 0 && k % 2 == 1 && !counter[0]) {
135-
for (int i = 1; i < 101; ++i) {
136-
if (counter[i]) {
137-
ans -= 2 * i;
131+
if ((k & 1) && !cnt[0]) {
132+
for (int x = 1; x <= 100; ++x) {
133+
if (cnt[x]) {
134+
--cnt[x];
135+
++cnt[-x];
138136
break;
139137
}
140138
}
141139
}
140+
int ans = 0;
141+
for (auto& [x, v] : cnt) {
142+
ans += x * v;
143+
}
142144
return ans;
143145
}
144146
};
@@ -147,34 +149,32 @@ public:
147149
### **Go**
148150
149151
```cpp
150-
func largestSumAfterKNegations(nums []int, k int) int {
151-
ans := 0
152-
counter := make(map[int]int)
153-
for _, num := range nums {
154-
ans += num
155-
counter[num]++
152+
func largestSumAfterKNegations(nums []int, k int) (ans int) {
153+
cnt := map[int]int{}
154+
for _, x := range nums {
155+
cnt[x]++
156156
}
157-
for i := -100; i < 0; i++ {
158-
if counter[i] > 0 {
159-
ops := min(counter[i], k)
160-
ans -= (i * ops * 2)
161-
counter[i] -= ops
162-
counter[-i] += ops
163-
k -= ops
164-
if k == 0 {
165-
break
166-
}
157+
for x := -100; x < 0 && k > 0; x++ {
158+
if cnt[x] > 0 {
159+
m := min(k, cnt[x])
160+
cnt[x] -= m
161+
cnt[-x] += m
162+
k -= m
167163
}
168164
}
169-
if k > 0 && k%2 == 1 && counter[0] == 0 {
170-
for i := 1; i < 101; i++ {
171-
if counter[i] > 0 {
172-
ans -= 2 * i
165+
if k&1 == 1 && cnt[0] == 0 {
166+
for x := 1; x <= 100; x++ {
167+
if cnt[x] > 0 {
168+
cnt[x]--
169+
cnt[-x]++
173170
break
174171
}
175172
}
176173
}
177-
return ans
174+
for x, v := range cnt {
175+
ans += x * v
176+
}
177+
return
178178
}
179179
180180
func min(a, b int) int {

0 commit comments

Comments
 (0)