Skip to content

feat: update lc problems #3310

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 4 commits into from
Jul 23, 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
8 changes: 4 additions & 4 deletions lcof2/剑指 Offer II 073. 狒狒吃香蕉/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,22 +189,22 @@ class Solution {
func minEatingSpeed(_ piles: [Int], _ h: Int) -> Int {
var left = 1
var right = piles.max() ?? 0

while left < right {
let mid = (left + right) / 2
var hours = 0

for pile in piles {
hours += (pile + mid - 1) / mid
}

if hours <= h {
right = mid
} else {
left = mid + 1
}
}

return left
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一:快慢指针

快慢指针法是一种用于解决链表中的问题的常用技巧。我们可以维护两个指针,一个慢指针 $\textit{slow}$ 和一个快指针 $\textit{fast}$。初始时 $\textit{slow}$ 指向一个虚拟节点,该虚拟节点的 $\textit{next}$ 指针指向链表的头节点 $\textit{head}$,而 $\textit{fast}$ 指向链表的头节点 $\textit{head}$。

然后,我们每次将慢指针向后移动一个位置,将快指针向后移动两个位置,直到快指针到达链表的末尾。此时,慢指针指向的节点的下一个节点就是链表的中间节点。我们将慢指针指向的节点的 $\textit{next}$ 指针指向下下个节点,即可删除中间节点。

时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand Down Expand Up @@ -197,15 +203,14 @@ func deleteMiddle(head *ListNode) *ListNode {
*/

function deleteMiddle(head: ListNode | null): ListNode | null {
if (!head || !head.next) return null;
let fast = head.next,
slow = head;
while (fast.next && fast.next.next) {
const dummy = new ListNode(0, head);
let [slow, fast] = [dummy, head];
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
slow.next = slow.next.next;
return head;
return dummy.next;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,13 @@ Node 0 with value 2 is the only node remaining after removing node 1.</pre>

<!-- solution:start -->

### Solution 1
### Solution 1: Fast and Slow Pointers

The fast and slow pointer technique is a common method used to solve problems related to linked lists. We can maintain two pointers, a slow pointer $\textit{slow}$ and a fast pointer $\textit{fast}$. Initially, $\textit{slow}$ points to a dummy node, whose $\textit{next}$ pointer points to the head node $\textit{head}$ of the list, while $\textit{fast}$ points to the head node $\textit{head}$.

Then, we move the slow pointer one position backward and the fast pointer two positions backward each time, until the fast pointer reaches the end of the list. At this point, the node next to the node pointed by the slow pointer is the middle node of the list. We can remove the middle node by setting the $\textit{next}$ pointer of the node pointed by the slow pointer to point to the next next node.

The time complexity is $O(n)$, where $n$ is the length of the list. The space complexity is $O(1)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -189,15 +195,14 @@ func deleteMiddle(head *ListNode) *ListNode {
*/

function deleteMiddle(head: ListNode | null): ListNode | null {
if (!head || !head.next) return null;
let fast = head.next,
slow = head;
while (fast.next && fast.next.next) {
const dummy = new ListNode(0, head);
let [slow, fast] = [dummy, head];
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
slow.next = slow.next.next;
return head;
return dummy.next;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@
*/

function deleteMiddle(head: ListNode | null): ListNode | null {
if (!head || !head.next) return null;
let fast = head.next,
slow = head;
while (fast.next && fast.next.next) {
const dummy = new ListNode(0, head);
let [slow, fast] = [dummy, head];
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
slow.next = slow.next.next;
return head;
return dummy.next;
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class Solution:
else:
mi1 = x
ans = max(ans - mi1 + mx1, ans - mi2 + mx2, -1)
return -1 if ans % 2 else ans
return -1 if ans < 0 else ans
```

#### Java
Expand Down Expand Up @@ -141,8 +141,8 @@ class Solution {
mi1 = nums[i];
}
}
ans = Math.max(-1, Math.max(ans - mi1 + mx1, ans - mi2 + mx2));
return ans % 2 != 0 ? -1 : ans;
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? -1 : ans;
}
}
```
Expand Down Expand Up @@ -180,7 +180,7 @@ public:
}
}
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans % 2 || ans < 0 ? -1 : ans;
return ans < 0 ? -1 : ans;
}
};
```
Expand Down Expand Up @@ -216,13 +216,50 @@ func largestEvenSum(nums []int, k int) int64 {
}
}
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
if ans%2 != 0 {
if ans%2 < 0 {
return -1
}
return int64(ans)
}
```

#### TypeScript

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

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,20 @@ No subsequence of nums with length 1 has an even sum.

<!-- solution:start -->

### Solution 1
### Solution 1: Greedy + Sorting

We notice that the problem involves selecting a subsequence, so we can consider sorting the array first.

Next, we greedily select the largest $k$ numbers. If the sum of these numbers is even, we directly return this sum $ans$.

Otherwise, we have two greedy strategies:

1. Among the largest $k$ numbers, find the smallest even number $mi1$, and then among the remaining $n - k$ numbers, find the largest odd number $mx1$. Replace $mi1$ with $mx1$. If such a replacement exists, then the sum after replacement $ans - mi1 + mx1$ is guaranteed to be even;
2. Among the largest $k$ numbers, find the smallest odd number $mi2$, and then among the remaining $n - k$ numbers, find the largest even number $mx2$. Replace $mi2$ with $mx2$. If such a replacement exists, then the sum after replacement $ans - mi2 + mx2$ is guaranteed to be even.

We take the largest even sum as the answer. If no even sum exists, return $-1$.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of the array.

<!-- tabs:start -->

Expand All @@ -94,7 +107,7 @@ class Solution:
else:
mi1 = x
ans = max(ans - mi1 + mx1, ans - mi2 + mx2, -1)
return -1 if ans % 2 else ans
return -1 if ans < 0 else ans
```

#### Java
Expand Down Expand Up @@ -128,8 +141,8 @@ class Solution {
mi1 = nums[i];
}
}
ans = Math.max(-1, Math.max(ans - mi1 + mx1, ans - mi2 + mx2));
return ans % 2 != 0 ? -1 : ans;
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? -1 : ans;
}
}
```
Expand Down Expand Up @@ -167,7 +180,7 @@ public:
}
}
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans % 2 || ans < 0 ? -1 : ans;
return ans < 0 ? -1 : ans;
}
};
```
Expand Down Expand Up @@ -203,13 +216,50 @@ func largestEvenSum(nums []int, k int) int64 {
}
}
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
if ans%2 != 0 {
if ans%2 < 0 {
return -1
}
return int64(ans)
}
```

#### TypeScript

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

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ class Solution {
}
}
ans = max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans % 2 || ans < 0 ? -1 : ans;
return ans < 0 ? -1 : ans;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func largestEvenSum(nums []int, k int) int64 {
}
}
ans = max(-1, max(ans-mi1+mx1, ans-mi2+mx2))
if ans%2 != 0 {
if ans%2 < 0 {
return -1
}
return int64(ans)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public long largestEvenSum(int[] nums, int k) {
mi1 = nums[i];
}
}
ans = Math.max(-1, Math.max(ans - mi1 + mx1, ans - mi2 + mx2));
return ans % 2 != 0 ? -1 : ans;
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? -1 : ans;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ def largestEvenSum(self, nums: List[int], k: int) -> int:
else:
mi1 = x
ans = max(ans - mi1 + mx1, ans - mi2 + mx2, -1)
return -1 if ans % 2 else ans
return -1 if ans < 0 else ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function largestEvenSum(nums: number[], k: number): number {
nums.sort((a, b) => a - b);
let ans = 0;
const n = nums.length;
for (let i = 0; i < k; ++i) {
ans += nums[n - i - 1];
}
if (ans % 2 === 0) {
return ans;
}
const inf = 1 << 29;
let mx1 = -inf,
mx2 = -inf;
for (let i = 0; i < n - k; ++i) {
if (nums[i] % 2 === 1) {
mx1 = nums[i];
} else {
mx2 = nums[i];
}
}
let mi1 = inf,
mi2 = inf;
for (let i = n - 1; i >= n - k; --i) {
if (nums[i] % 2 === 1) {
mi2 = nums[i];
} else {
mi1 = nums[i];
}
}
ans = Math.max(ans - mi1 + mx1, ans - mi2 + mx2);
return ans < 0 ? -1 : ans;
}
Loading
Loading