Skip to content

Commit 9d87743

Browse files
authored
feat: update lc problems (#3345)
1 parent 7613021 commit 9d87743

File tree

36 files changed

+528
-115
lines changed

36 files changed

+528
-115
lines changed

lcp/LCP 40. 心算挑战/README.md

+122-58
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,20 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2040.%20%E5%BF%83%
4242

4343
<!-- solution:start -->
4444

45-
### 方法一:排序 + 贪心
45+
### 方法一:贪心 + 排序
4646

47-
排序先取最大的 $cnt$ 个数,如果和为偶数则直接返回答案
47+
我们注意到,题目选取的是子序列,因此我们可以考虑先对数组进行排序
4848

49-
否则,找一个已取的最小奇数换成剩余未取的最大偶数,或者找一个已取的最小偶数换成剩下未取的最大奇数,取两者中较大的
49+
接下来,我们先贪心地选取最大的 $\textit{cnt}$ 个数,如果这些数的和为偶数,则直接返回这个和 $ans$
5050

51-
时间复杂度 $O(nlogn)$。
51+
否则,我们有两种贪心策略:
52+
53+
1. 在最大的 $\textit{cnt}$ 个数中,找到一个最小的偶数 $mi1$,然后在剩下的 $n - \textit{cnt}$ 个数中,找到一个最大的奇数 $mx1$,将 $mi1$ 替换为 $mx1$,如果存在这样的替换,那么替换后的和 $ans - mi1 + mx1$ 一定是偶数;
54+
1. 在最大的 $\textit{cnt}$ 个数中,找到一个最小的奇数 $mi2$,然后在剩下的 $n - \textit{cnt}$ 个数中,找到一个最大的偶数 $mx2$,将 $mi2$ 替换为 $mx2$,如果存在这样的替换,那么替换后的和 $ans - mi2 + mx2$ 一定是偶数。
55+
56+
我们取最大的偶数和作为答案。如果不存在偶数和,则返回 $0$。
57+
58+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组长度。
5259

5360
<!-- tabs:start -->
5461

@@ -57,16 +64,25 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2040.%20%E5%BF%83%
5764
```python
5865
class Solution:
5966
def maxmiumScore(self, cards: List[int], cnt: int) -> int:
60-
cards.sort(reverse=True)
61-
t = cards[:cnt]
62-
ans = sum(t)
67+
cards.sort()
68+
ans = sum(cards[-cnt:])
6369
if ans % 2 == 0:
6470
return ans
65-
a = min([v for v in t if v & 1], default=inf)
66-
b = min([v for v in t if v % 2 == 0], default=inf)
67-
c = max([v for v in cards[cnt:] if v % 2 == 0], default=-inf)
68-
d = max([v for v in cards[cnt:] if v & 1], default=-inf)
69-
return max(ans - a + c, ans - b + d, 0)
71+
n = len(cards)
72+
mx1 = mx2 = -inf
73+
for x in cards[: n - cnt]:
74+
if x & 1:
75+
mx1 = x
76+
else:
77+
mx2 = x
78+
mi1 = mi2 = inf
79+
for x in cards[-cnt:][::-1]:
80+
if x & 1:
81+
mi2 = x
82+
else:
83+
mi1 = x
84+
ans = max(ans - mi1 + mx1, ans - mi2 + mx2, -1)
85+
return 0 if ans < 0 else ans
7086
```
7187

7288
#### Java
@@ -83,26 +99,25 @@ class Solution {
8399
if (ans % 2 == 0) {
84100
return ans;
85101
}
86-
int inf = 0x3f3f3f3f;
87-
int a = inf, b = inf;
88-
for (int i = 0; i < cnt; ++i) {
89-
int v = cards[n - i - 1];
90-
if (v % 2 == 1) {
91-
a = Math.min(a, v);
102+
final int inf = 1 << 29;
103+
int mx1 = -inf, mx2 = -inf;
104+
for (int i = 0; i < n - cnt; ++i) {
105+
if (cards[i] % 2 == 1) {
106+
mx1 = cards[i];
92107
} else {
93-
b = Math.min(b, v);
108+
mx2 = cards[i];
94109
}
95110
}
96-
int c = -inf, d = -inf;
97-
for (int i = cnt; i < n; ++i) {
98-
int v = cards[n - i - 1];
99-
if (v % 2 == 0) {
100-
c = Math.max(c, v);
111+
int mi1 = inf, mi2 = inf;
112+
for (int i = n - 1; i >= n - cnt; --i) {
113+
if (cards[i] % 2 == 1) {
114+
mi2 = cards[i];
101115
} else {
102-
d = Math.max(d, v);
116+
mi1 = cards[i];
103117
}
104118
}
105-
return Math.max(0, Math.max(ans - a + c, ans - b + d));
119+
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
120+
return ans < 0 ? 0 : ans;
106121
}
107122
}
108123
```
@@ -114,27 +129,33 @@ class Solution {
114129
public:
115130
int maxmiumScore(vector<int>& cards, int cnt) {
116131
sort(cards.begin(), cards.end());
117-
reverse(cards.begin(), cards.end());
118-
int ans = 0, n = cards.size();
119-
for (int i = 0; i < cnt; ++i) ans += cards[i];
120-
if (ans % 2 == 0) return ans;
121-
int inf = 0x3f3f3f3f;
122-
int a = inf, b = inf, c = -inf, d = -inf;
132+
int ans = 0;
133+
int n = cards.size();
123134
for (int i = 0; i < cnt; ++i) {
124-
int v = cards[i];
125-
if (v % 2 == 1)
126-
a = min(a, v);
127-
else
128-
b = min(b, v);
135+
ans += cards[n - i - 1];
129136
}
130-
for (int i = cnt; i < n; ++i) {
131-
int v = cards[i];
132-
if (v % 2 == 0)
133-
c = max(c, v);
134-
else
135-
d = max(d, v);
137+
if (ans % 2 == 0) {
138+
return ans;
139+
}
140+
const int inf = 1 << 29;
141+
int mx1 = -inf, mx2 = -inf;
142+
for (int i = 0; i < n - cnt; ++i) {
143+
if (cards[i] % 2) {
144+
mx1 = cards[i];
145+
} else {
146+
mx2 = cards[i];
147+
}
136148
}
137-
return max(0, max(ans - a + c, ans - b + d));
149+
int mi1 = inf, mi2 = inf;
150+
for (int i = n - 1; i >= n - cnt; --i) {
151+
if (cards[i] % 2) {
152+
mi2 = cards[i];
153+
} else {
154+
mi1 = cards[i];
155+
}
156+
}
157+
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
158+
return ans < 0 ? 0 : ans;
138159
}
139160
};
140161
```
@@ -143,31 +164,74 @@ public:
143164
144165
```go
145166
func maxmiumScore(cards []int, cnt int) int {
167+
sort.Ints(cards)
146168
ans := 0
147-
sort.Slice(cards, func(i, j int) bool { return cards[i] > cards[j] })
148-
for _, v := range cards[:cnt] {
149-
ans += v
169+
n := len(cards)
170+
for i := 0; i < cnt; i++ {
171+
ans += cards[n-1-i]
150172
}
151173
if ans%2 == 0 {
152174
return ans
153175
}
154-
inf := 0x3f3f3f3f
155-
a, b, c, d := inf, inf, -inf, -inf
156-
for _, v := range cards[:cnt] {
157-
if v%2 == 1 {
158-
a = min(a, v)
176+
const inf = 1 << 29
177+
mx1, mx2 := -inf, -inf
178+
for _, x := range cards[:n-cnt] {
179+
if x%2 == 1 {
180+
mx1 = x
159181
} else {
160-
b = min(b, v)
182+
mx2 = x
161183
}
162184
}
163-
for _, v := range cards[cnt:] {
164-
if v%2 == 0 {
165-
c = max(c, v)
185+
mi1, mi2 := inf, inf
186+
for i := n - 1; i >= n-cnt; i-- {
187+
if cards[i]%2 == 1 {
188+
mi2 = cards[i]
166189
} else {
167-
d = max(d, v)
190+
mi1 = cards[i]
168191
}
169192
}
170-
return max(0, max(ans-a+c, ans-b+d))
193+
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
194+
if ans < 0 {
195+
return 0
196+
}
197+
return ans
198+
}
199+
```
200+
201+
#### TypeScript
202+
203+
```ts
204+
function maxmiumScore(cards: number[], cnt: number): number {
205+
cards.sort((a, b) => a - b);
206+
let ans = 0;
207+
const n = cards.length;
208+
for (let i = 0; i < cnt; ++i) {
209+
ans += cards[n - i - 1];
210+
}
211+
if (ans % 2 === 0) {
212+
return ans;
213+
}
214+
const inf = 1 << 29;
215+
let mx1 = -inf,
216+
mx2 = -inf;
217+
for (let i = 0; i < n - cnt; ++i) {
218+
if (cards[i] % 2 === 1) {
219+
mx1 = cards[i];
220+
} else {
221+
mx2 = cards[i];
222+
}
223+
}
224+
let mi1 = inf,
225+
mi2 = inf;
226+
for (let i = n - 1; i >= n - cnt; --i) {
227+
if (cards[i] % 2 === 1) {
228+
mi2 = cards[i];
229+
} else {
230+
mi1 = cards[i];
231+
}
232+
}
233+
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
234+
return ans < 0 ? 0 : ans;
171235
}
172236
```
173237

lcp/LCP 40. 心算挑战/Solution.cpp

+25-19
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,32 @@ class Solution {
22
public:
33
int maxmiumScore(vector<int>& cards, int cnt) {
44
sort(cards.begin(), cards.end());
5-
reverse(cards.begin(), cards.end());
6-
int ans = 0, n = cards.size();
7-
for (int i = 0; i < cnt; ++i) ans += cards[i];
8-
if (ans % 2 == 0) return ans;
9-
int inf = 0x3f3f3f3f;
10-
int a = inf, b = inf, c = -inf, d = -inf;
5+
int ans = 0;
6+
int n = cards.size();
117
for (int i = 0; i < cnt; ++i) {
12-
int v = cards[i];
13-
if (v % 2 == 1)
14-
a = min(a, v);
15-
else
16-
b = min(b, v);
8+
ans += cards[n - i - 1];
179
}
18-
for (int i = cnt; i < n; ++i) {
19-
int v = cards[i];
20-
if (v % 2 == 0)
21-
c = max(c, v);
22-
else
23-
d = max(d, v);
10+
if (ans % 2 == 0) {
11+
return ans;
2412
}
25-
return max(0, max(ans - a + c, ans - b + d));
13+
const int inf = 1 << 29;
14+
int mx1 = -inf, mx2 = -inf;
15+
for (int i = 0; i < n - cnt; ++i) {
16+
if (cards[i] % 2) {
17+
mx1 = cards[i];
18+
} else {
19+
mx2 = cards[i];
20+
}
21+
}
22+
int mi1 = inf, mi2 = inf;
23+
for (int i = n - 1; i >= n - cnt; --i) {
24+
if (cards[i] % 2) {
25+
mi2 = cards[i];
26+
} else {
27+
mi1 = cards[i];
28+
}
29+
}
30+
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
31+
return ans < 0 ? 0 : ans;
2632
}
27-
};
33+
};

lcp/LCP 40. 心算挑战/Solution.go

+21-15
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
11
func maxmiumScore(cards []int, cnt int) int {
2+
sort.Ints(cards)
23
ans := 0
3-
sort.Slice(cards, func(i, j int) bool { return cards[i] > cards[j] })
4-
for _, v := range cards[:cnt] {
5-
ans += v
4+
n := len(cards)
5+
for i := 0; i < cnt; i++ {
6+
ans += cards[n-1-i]
67
}
78
if ans%2 == 0 {
89
return ans
910
}
10-
inf := 0x3f3f3f3f
11-
a, b, c, d := inf, inf, -inf, -inf
12-
for _, v := range cards[:cnt] {
13-
if v%2 == 1 {
14-
a = min(a, v)
11+
const inf = 1 << 29
12+
mx1, mx2 := -inf, -inf
13+
for _, x := range cards[:n-cnt] {
14+
if x%2 == 1 {
15+
mx1 = x
1516
} else {
16-
b = min(b, v)
17+
mx2 = x
1718
}
1819
}
19-
for _, v := range cards[cnt:] {
20-
if v%2 == 0 {
21-
c = max(c, v)
20+
mi1, mi2 := inf, inf
21+
for i := n - 1; i >= n-cnt; i-- {
22+
if cards[i]%2 == 1 {
23+
mi2 = cards[i]
2224
} else {
23-
d = max(d, v)
25+
mi1 = cards[i]
2426
}
2527
}
26-
return max(0, max(ans-a+c, ans-b+d))
27-
}
28+
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
29+
if ans < 0 {
30+
return 0
31+
}
32+
return ans
33+
}

lcp/LCP 40. 心算挑战/Solution.java

+14-15
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,24 @@ public int maxmiumScore(int[] cards, int cnt) {
99
if (ans % 2 == 0) {
1010
return ans;
1111
}
12-
int inf = 0x3f3f3f3f;
13-
int a = inf, b = inf;
14-
for (int i = 0; i < cnt; ++i) {
15-
int v = cards[n - i - 1];
16-
if (v % 2 == 1) {
17-
a = Math.min(a, v);
12+
final int inf = 1 << 29;
13+
int mx1 = -inf, mx2 = -inf;
14+
for (int i = 0; i < n - cnt; ++i) {
15+
if (cards[i] % 2 == 1) {
16+
mx1 = cards[i];
1817
} else {
19-
b = Math.min(b, v);
18+
mx2 = cards[i];
2019
}
2120
}
22-
int c = -inf, d = -inf;
23-
for (int i = cnt; i < n; ++i) {
24-
int v = cards[n - i - 1];
25-
if (v % 2 == 0) {
26-
c = Math.max(c, v);
21+
int mi1 = inf, mi2 = inf;
22+
for (int i = n - 1; i >= n - cnt; --i) {
23+
if (cards[i] % 2 == 1) {
24+
mi2 = cards[i];
2725
} else {
28-
d = Math.max(d, v);
26+
mi1 = cards[i];
2927
}
3028
}
31-
return Math.max(0, Math.max(ans - a + c, ans - b + d));
29+
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
30+
return ans < 0 ? 0 : ans;
3231
}
33-
}
32+
}

0 commit comments

Comments
 (0)