Skip to content

feat: update lc problems #3345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 122 additions & 58 deletions lcp/LCP 40. 心算挑战/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,20 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2040.%20%E5%BF%83%

<!-- solution:start -->

### 方法一:排序 + 贪心
### 方法一:贪心 + 排序

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

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

时间复杂度 $O(nlogn)$。
否则,我们有两种贪心策略:

1. 在最大的 $\textit{cnt}$ 个数中,找到一个最小的偶数 $mi1$,然后在剩下的 $n - \textit{cnt}$ 个数中,找到一个最大的奇数 $mx1$,将 $mi1$ 替换为 $mx1$,如果存在这样的替换,那么替换后的和 $ans - mi1 + mx1$ 一定是偶数;
1. 在最大的 $\textit{cnt}$ 个数中,找到一个最小的奇数 $mi2$,然后在剩下的 $n - \textit{cnt}$ 个数中,找到一个最大的偶数 $mx2$,将 $mi2$ 替换为 $mx2$,如果存在这样的替换,那么替换后的和 $ans - mi2 + mx2$ 一定是偶数。

我们取最大的偶数和作为答案。如果不存在偶数和,则返回 $0$。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组长度。

<!-- tabs:start -->

Expand All @@ -57,16 +64,25 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2040.%20%E5%BF%83%
```python
class Solution:
def maxmiumScore(self, cards: List[int], cnt: int) -> int:
cards.sort(reverse=True)
t = cards[:cnt]
ans = sum(t)
cards.sort()
ans = sum(cards[-cnt:])
if ans % 2 == 0:
return ans
a = min([v for v in t if v & 1], default=inf)
b = min([v for v in t if v % 2 == 0], default=inf)
c = max([v for v in cards[cnt:] if v % 2 == 0], default=-inf)
d = max([v for v in cards[cnt:] if v & 1], default=-inf)
return max(ans - a + c, ans - b + d, 0)
n = len(cards)
mx1 = mx2 = -inf
for x in cards[: n - cnt]:
if x & 1:
mx1 = x
else:
mx2 = x
mi1 = mi2 = inf
for x in cards[-cnt:][::-1]:
if x & 1:
mi2 = x
else:
mi1 = x
ans = max(ans - mi1 + mx1, ans - mi2 + mx2, -1)
return 0 if ans < 0 else ans
```

#### Java
Expand All @@ -83,26 +99,25 @@ class Solution {
if (ans % 2 == 0) {
return ans;
}
int inf = 0x3f3f3f3f;
int a = inf, b = inf;
for (int i = 0; i < cnt; ++i) {
int v = cards[n - i - 1];
if (v % 2 == 1) {
a = Math.min(a, v);
final int inf = 1 << 29;
int mx1 = -inf, mx2 = -inf;
for (int i = 0; i < n - cnt; ++i) {
if (cards[i] % 2 == 1) {
mx1 = cards[i];
} else {
b = Math.min(b, v);
mx2 = cards[i];
}
}
int c = -inf, d = -inf;
for (int i = cnt; i < n; ++i) {
int v = cards[n - i - 1];
if (v % 2 == 0) {
c = Math.max(c, v);
int mi1 = inf, mi2 = inf;
for (int i = n - 1; i >= n - cnt; --i) {
if (cards[i] % 2 == 1) {
mi2 = cards[i];
} else {
d = Math.max(d, v);
mi1 = cards[i];
}
}
return Math.max(0, Math.max(ans - a + c, ans - b + d));
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? 0 : ans;
}
}
```
Expand All @@ -114,27 +129,33 @@ class Solution {
public:
int maxmiumScore(vector<int>& cards, int cnt) {
sort(cards.begin(), cards.end());
reverse(cards.begin(), cards.end());
int ans = 0, n = cards.size();
for (int i = 0; i < cnt; ++i) ans += cards[i];
if (ans % 2 == 0) return ans;
int inf = 0x3f3f3f3f;
int a = inf, b = inf, c = -inf, d = -inf;
int ans = 0;
int n = cards.size();
for (int i = 0; i < cnt; ++i) {
int v = cards[i];
if (v % 2 == 1)
a = min(a, v);
else
b = min(b, v);
ans += cards[n - i - 1];
}
for (int i = cnt; i < n; ++i) {
int v = cards[i];
if (v % 2 == 0)
c = max(c, v);
else
d = max(d, v);
if (ans % 2 == 0) {
return ans;
}
const int inf = 1 << 29;
int mx1 = -inf, mx2 = -inf;
for (int i = 0; i < n - cnt; ++i) {
if (cards[i] % 2) {
mx1 = cards[i];
} else {
mx2 = cards[i];
}
}
return max(0, max(ans - a + c, ans - b + d));
int mi1 = inf, mi2 = inf;
for (int i = n - 1; i >= n - cnt; --i) {
if (cards[i] % 2) {
mi2 = cards[i];
} else {
mi1 = cards[i];
}
}
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? 0 : ans;
}
};
```
Expand All @@ -143,31 +164,74 @@ public:

```go
func maxmiumScore(cards []int, cnt int) int {
sort.Ints(cards)
ans := 0
sort.Slice(cards, func(i, j int) bool { return cards[i] > cards[j] })
for _, v := range cards[:cnt] {
ans += v
n := len(cards)
for i := 0; i < cnt; i++ {
ans += cards[n-1-i]
}
if ans%2 == 0 {
return ans
}
inf := 0x3f3f3f3f
a, b, c, d := inf, inf, -inf, -inf
for _, v := range cards[:cnt] {
if v%2 == 1 {
a = min(a, v)
const inf = 1 << 29
mx1, mx2 := -inf, -inf
for _, x := range cards[:n-cnt] {
if x%2 == 1 {
mx1 = x
} else {
b = min(b, v)
mx2 = x
}
}
for _, v := range cards[cnt:] {
if v%2 == 0 {
c = max(c, v)
mi1, mi2 := inf, inf
for i := n - 1; i >= n-cnt; i-- {
if cards[i]%2 == 1 {
mi2 = cards[i]
} else {
d = max(d, v)
mi1 = cards[i]
}
}
return max(0, max(ans-a+c, ans-b+d))
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
if ans < 0 {
return 0
}
return ans
}
```

#### TypeScript

```ts
function maxmiumScore(cards: number[], cnt: number): number {
cards.sort((a, b) => a - b);
let ans = 0;
const n = cards.length;
for (let i = 0; i < cnt; ++i) {
ans += cards[n - i - 1];
}
if (ans % 2 === 0) {
return ans;
}
const inf = 1 << 29;
let mx1 = -inf,
mx2 = -inf;
for (let i = 0; i < n - cnt; ++i) {
if (cards[i] % 2 === 1) {
mx1 = cards[i];
} else {
mx2 = cards[i];
}
}
let mi1 = inf,
mi2 = inf;
for (let i = n - 1; i >= n - cnt; --i) {
if (cards[i] % 2 === 1) {
mi2 = cards[i];
} else {
mi1 = cards[i];
}
}
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? 0 : ans;
}
```

Expand Down
44 changes: 25 additions & 19 deletions lcp/LCP 40. 心算挑战/Solution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,32 @@ class Solution {
public:
int maxmiumScore(vector<int>& cards, int cnt) {
sort(cards.begin(), cards.end());
reverse(cards.begin(), cards.end());
int ans = 0, n = cards.size();
for (int i = 0; i < cnt; ++i) ans += cards[i];
if (ans % 2 == 0) return ans;
int inf = 0x3f3f3f3f;
int a = inf, b = inf, c = -inf, d = -inf;
int ans = 0;
int n = cards.size();
for (int i = 0; i < cnt; ++i) {
int v = cards[i];
if (v % 2 == 1)
a = min(a, v);
else
b = min(b, v);
ans += cards[n - i - 1];
}
for (int i = cnt; i < n; ++i) {
int v = cards[i];
if (v % 2 == 0)
c = max(c, v);
else
d = max(d, v);
if (ans % 2 == 0) {
return ans;
}
return max(0, max(ans - a + c, ans - b + d));
const int inf = 1 << 29;
int mx1 = -inf, mx2 = -inf;
for (int i = 0; i < n - cnt; ++i) {
if (cards[i] % 2) {
mx1 = cards[i];
} else {
mx2 = cards[i];
}
}
int mi1 = inf, mi2 = inf;
for (int i = n - 1; i >= n - cnt; --i) {
if (cards[i] % 2) {
mi2 = cards[i];
} else {
mi1 = cards[i];
}
}
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? 0 : ans;
}
};
};
36 changes: 21 additions & 15 deletions lcp/LCP 40. 心算挑战/Solution.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
func maxmiumScore(cards []int, cnt int) int {
sort.Ints(cards)
ans := 0
sort.Slice(cards, func(i, j int) bool { return cards[i] > cards[j] })
for _, v := range cards[:cnt] {
ans += v
n := len(cards)
for i := 0; i < cnt; i++ {
ans += cards[n-1-i]
}
if ans%2 == 0 {
return ans
}
inf := 0x3f3f3f3f
a, b, c, d := inf, inf, -inf, -inf
for _, v := range cards[:cnt] {
if v%2 == 1 {
a = min(a, v)
const inf = 1 << 29
mx1, mx2 := -inf, -inf
for _, x := range cards[:n-cnt] {
if x%2 == 1 {
mx1 = x
} else {
b = min(b, v)
mx2 = x
}
}
for _, v := range cards[cnt:] {
if v%2 == 0 {
c = max(c, v)
mi1, mi2 := inf, inf
for i := n - 1; i >= n-cnt; i-- {
if cards[i]%2 == 1 {
mi2 = cards[i]
} else {
d = max(d, v)
mi1 = cards[i]
}
}
return max(0, max(ans-a+c, ans-b+d))
}
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
if ans < 0 {
return 0
}
return ans
}
29 changes: 14 additions & 15 deletions lcp/LCP 40. 心算挑战/Solution.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,24 @@ public int maxmiumScore(int[] cards, int cnt) {
if (ans % 2 == 0) {
return ans;
}
int inf = 0x3f3f3f3f;
int a = inf, b = inf;
for (int i = 0; i < cnt; ++i) {
int v = cards[n - i - 1];
if (v % 2 == 1) {
a = Math.min(a, v);
final int inf = 1 << 29;
int mx1 = -inf, mx2 = -inf;
for (int i = 0; i < n - cnt; ++i) {
if (cards[i] % 2 == 1) {
mx1 = cards[i];
} else {
b = Math.min(b, v);
mx2 = cards[i];
}
}
int c = -inf, d = -inf;
for (int i = cnt; i < n; ++i) {
int v = cards[n - i - 1];
if (v % 2 == 0) {
c = Math.max(c, v);
int mi1 = inf, mi2 = inf;
for (int i = n - 1; i >= n - cnt; --i) {
if (cards[i] % 2 == 1) {
mi2 = cards[i];
} else {
d = Math.max(d, v);
mi1 = cards[i];
}
}
return Math.max(0, Math.max(ans - a + c, ans - b + d));
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? 0 : ans;
}
}
}
Loading
Loading