From 64f33783bd6d769f1035e5e82132da754ab4ec4d Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 3 Jan 2024 19:54:47 +0800 Subject: [PATCH] feat: update solutions to lc problems * No.2487.Remove Nodes From Linked List * No.2806.Account Balance After Rounded Purchase * No.2807.Insert Greatest Common Divisors in Linked List * No.2808.Minimum Seconds to Equalize a Circular Array * No.2809.Minimum Time to Make Array Sum At Most x * No.2810.Faulty Keyboard * No.2811.Check if it is Possible to Split Array * No.2985.Calculate Compressed Mean * No.2987.Find Expensive Cities * No.2988.Manager of the Largest Department --- .../README.md | 58 +++++++------------ .../README_EN.md | 58 +++++++------------ .../Solution.cpp | 58 ++++++++----------- .../Solution.go | 21 ++----- .../Solution.java | 22 +++---- .../Solution.py | 39 ++++++------- .../Solution.ts | 20 ++----- .../README_EN.md | 6 ++ .../README.md | 22 +++---- .../README_EN.md | 24 ++++---- .../Solution.cpp | 4 +- .../Solution.go | 5 +- .../Solution.java | 4 +- .../Solution.ts | 5 +- .../README_EN.md | 10 ++++ .../README_EN.md | 29 ++++++++++ .../2810.Faulty Keyboard/README_EN.md | 10 ++++ .../README.md | 2 +- .../README_EN.md | 28 +++++++++ .../2985.Calculate Compressed Mean/README.md | 4 ++ .../README_EN.md | 4 ++ .../2987.Find Expensive Cities/README.md | 4 ++ .../2987.Find Expensive Cities/README_EN.md | 4 ++ .../README.md | 4 ++ .../README_EN.md | 4 ++ 25 files changed, 232 insertions(+), 217 deletions(-) diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/README.md b/solution/2400-2499/2487.Remove Nodes From Linked List/README.md index 16a68fe38c876..6a5466725f763 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/README.md +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/README.md @@ -101,16 +101,13 @@ class Solution: # self.next = next class Solution: def removeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]: - dummy = ListNode(next=head) + dummy = ListNode(inf, head) cur = head - stk = [] + stk = [dummy] while cur: - while stk and stk[-1].val < cur.val: + while stk[-1].val < cur.val: stk.pop() - if stk: - stk[-1].next = cur - else: - dummy.next = cur + stk[-1].next = cur stk.append(cur) cur = cur.next return dummy.next @@ -169,17 +166,14 @@ class Solution { */ class Solution { public ListNode removeNodes(ListNode head) { - ListNode dummy = new ListNode(0, head); + ListNode dummy = new ListNode(1 << 30, head); Deque stk = new ArrayDeque<>(); + stk.offerLast(dummy); for (ListNode cur = head; cur != null; cur = cur.next) { - while (!stk.isEmpty() && stk.peekLast().val < cur.val) { + while (stk.peekLast().val < cur.val) { stk.pollLast(); } - if (!stk.isEmpty()) { - stk.peekLast().next = cur; - } else { - dummy.next = cur; - } + stk.peekLast().next = cur; stk.offerLast(cur); } return dummy.next; @@ -240,18 +234,14 @@ public: class Solution { public: ListNode* removeNodes(ListNode* head) { - ListNode* dummy = new ListNode(0, head); + ListNode* dummy = new ListNode(1e9, head); ListNode* cur = head; - vector stk; + vector stk = {dummy}; for (ListNode* cur = head; cur; cur = cur->next) { - while (stk.size() && stk.back()->val < cur->val) { + while (stk.back()->val < cur->val) { stk.pop_back(); } - if (stk.size()) { - stk.back()->next = cur; - } else { - dummy->next = cur; - } + stk.back()->next = cur; stk.push_back(cur); } return dummy->next; @@ -301,17 +291,13 @@ func removeNodes(head *ListNode) *ListNode { * } */ func removeNodes(head *ListNode) *ListNode { - dummy := &ListNode{Next: head} - stk := []*ListNode{} + dummy := &ListNode{1 << 30, head} + stk := []*ListNode{dummy} for cur := head; cur != nil; cur = cur.Next { - for len(stk) > 0 && stk[len(stk)-1].Val < cur.Val { + for stk[len(stk)-1].Val < cur.Val { stk = stk[:len(stk)-1] } - if len(stk) > 0 { - stk[len(stk)-1].Next = cur - } else { - dummy.Next = cur - } + stk[len(stk)-1].Next = cur stk = append(stk, cur) } return dummy.Next @@ -369,17 +355,13 @@ function removeNodes(head: ListNode | null): ListNode | null { */ function removeNodes(head: ListNode | null): ListNode | null { - const dummy = new ListNode(0, head); - const stk: ListNode[] = []; + const dummy = new ListNode(Infinity, head); + const stk: ListNode[] = [dummy]; for (let cur = head; cur; cur = cur.next) { - while (stk.length && stk.at(-1)!.val < cur.val) { + while (stk.at(-1)!.val < cur.val) { stk.pop(); } - if (stk.length) { - stk.at(-1)!.next = cur; - } else { - dummy.next = cur; - } + stk.at(-1)!.next = cur; stk.push(cur); } return dummy.next; diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md b/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md index 1f27507a91ba8..c6ceffa9adc78 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md @@ -91,16 +91,13 @@ class Solution: # self.next = next class Solution: def removeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]: - dummy = ListNode(next=head) + dummy = ListNode(inf, head) cur = head - stk = [] + stk = [dummy] while cur: - while stk and stk[-1].val < cur.val: + while stk[-1].val < cur.val: stk.pop() - if stk: - stk[-1].next = cur - else: - dummy.next = cur + stk[-1].next = cur stk.append(cur) cur = cur.next return dummy.next @@ -157,17 +154,14 @@ class Solution { */ class Solution { public ListNode removeNodes(ListNode head) { - ListNode dummy = new ListNode(0, head); + ListNode dummy = new ListNode(1 << 30, head); Deque stk = new ArrayDeque<>(); + stk.offerLast(dummy); for (ListNode cur = head; cur != null; cur = cur.next) { - while (!stk.isEmpty() && stk.peekLast().val < cur.val) { + while (stk.peekLast().val < cur.val) { stk.pollLast(); } - if (!stk.isEmpty()) { - stk.peekLast().next = cur; - } else { - dummy.next = cur; - } + stk.peekLast().next = cur; stk.offerLast(cur); } return dummy.next; @@ -228,18 +222,14 @@ public: class Solution { public: ListNode* removeNodes(ListNode* head) { - ListNode* dummy = new ListNode(0, head); + ListNode* dummy = new ListNode(1e9, head); ListNode* cur = head; - vector stk; + vector stk = {dummy}; for (ListNode* cur = head; cur; cur = cur->next) { - while (stk.size() && stk.back()->val < cur->val) { + while (stk.back()->val < cur->val) { stk.pop_back(); } - if (stk.size()) { - stk.back()->next = cur; - } else { - dummy->next = cur; - } + stk.back()->next = cur; stk.push_back(cur); } return dummy->next; @@ -289,17 +279,13 @@ func removeNodes(head *ListNode) *ListNode { * } */ func removeNodes(head *ListNode) *ListNode { - dummy := &ListNode{Next: head} - stk := []*ListNode{} + dummy := &ListNode{1 << 30, head} + stk := []*ListNode{dummy} for cur := head; cur != nil; cur = cur.Next { - for len(stk) > 0 && stk[len(stk)-1].Val < cur.Val { + for stk[len(stk)-1].Val < cur.Val { stk = stk[:len(stk)-1] } - if len(stk) > 0 { - stk[len(stk)-1].Next = cur - } else { - dummy.Next = cur - } + stk[len(stk)-1].Next = cur stk = append(stk, cur) } return dummy.Next @@ -357,17 +343,13 @@ function removeNodes(head: ListNode | null): ListNode | null { */ function removeNodes(head: ListNode | null): ListNode | null { - const dummy = new ListNode(0, head); - const stk: ListNode[] = []; + const dummy = new ListNode(Infinity, head); + const stk: ListNode[] = [dummy]; for (let cur = head; cur; cur = cur.next) { - while (stk.length && stk.at(-1)!.val < cur.val) { + while (stk.at(-1)!.val < cur.val) { stk.pop(); } - if (stk.length) { - stk.at(-1)!.next = cur; - } else { - dummy.next = cur; - } + stk.at(-1)!.next = cur; stk.push(cur); } return dummy.next; diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.cpp b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.cpp index c83217c597632..cf1351b6e3eb6 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.cpp +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.cpp @@ -1,34 +1,26 @@ -/** - * Definition for singly-linked list. - * struct ListNode { - * int val; - * ListNode *next; - * ListNode() : val(0), next(nullptr) {} - * ListNode(int x) : val(x), next(nullptr) {} - * ListNode(int x, ListNode *next) : val(x), next(next) {} - * }; - */ -class Solution { -public: - ListNode* removeNodes(ListNode* head) { - vector nums; - while (head) { - nums.emplace_back(head->val); - head = head->next; - } - vector stk; - for (int v : nums) { - while (!stk.empty() && stk.back() < v) { - stk.pop_back(); - } - stk.push_back(v); - } - ListNode* dummy = new ListNode(); - head = dummy; - for (int v : stk) { - head->next = new ListNode(v); - head = head->next; - } - return dummy->next; - } +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + ListNode* removeNodes(ListNode* head) { + ListNode* dummy = new ListNode(1e9, head); + ListNode* cur = head; + vector stk = {dummy}; + for (ListNode* cur = head; cur; cur = cur->next) { + while (stk.back()->val < cur->val) { + stk.pop_back(); + } + stk.back()->next = cur; + stk.push_back(cur); + } + return dummy->next; + } }; \ No newline at end of file diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.go b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.go index fcefffa532460..9a4bb565bc837 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.go +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.go @@ -6,23 +6,14 @@ * } */ func removeNodes(head *ListNode) *ListNode { - nums := []int{} - for head != nil { - nums = append(nums, head.Val) - head = head.Next - } - stk := []int{} - for _, v := range nums { - for len(stk) > 0 && stk[len(stk)-1] < v { + dummy := &ListNode{1 << 30, head} + stk := []*ListNode{dummy} + for cur := head; cur != nil; cur = cur.Next { + for stk[len(stk)-1].Val < cur.Val { stk = stk[:len(stk)-1] } - stk = append(stk, v) - } - dummy := &ListNode{} - head = dummy - for _, v := range stk { - head.Next = &ListNode{Val: v} - head = head.Next + stk[len(stk)-1].Next = cur + stk = append(stk, cur) } return dummy.Next } \ No newline at end of file diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java index db2de45df6d50..404408aa83cfa 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java @@ -10,23 +10,15 @@ */ class Solution { public ListNode removeNodes(ListNode head) { - List nums = new ArrayList<>(); - while (head != null) { - nums.add(head.val); - head = head.next; - } - Deque stk = new ArrayDeque<>(); - for (int v : nums) { - while (!stk.isEmpty() && stk.peekLast() < v) { + ListNode dummy = new ListNode(1 << 30, head); + Deque stk = new ArrayDeque<>(); + stk.offerLast(dummy); + for (ListNode cur = head; cur != null; cur = cur.next) { + while (stk.peekLast().val < cur.val) { stk.pollLast(); } - stk.offerLast(v); - } - ListNode dummy = new ListNode(); - head = dummy; - while (!stk.isEmpty()) { - head.next = new ListNode(stk.pollFirst()); - head = head.next; + stk.peekLast().next = cur; + stk.offerLast(cur); } return dummy.next; } diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.py b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.py index b11db0144e316..e8cbd596639a6 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.py +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.py @@ -1,22 +1,17 @@ -# Definition for singly-linked list. -# class ListNode: -# def __init__(self, val=0, next=None): -# self.val = val -# self.next = next -class Solution: - def removeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]: - nums = [] - while head: - nums.append(head.val) - head = head.next - stk = [] - for v in nums: - while stk and stk[-1] < v: - stk.pop() - stk.append(v) - dummy = ListNode() - head = dummy - for v in stk: - head.next = ListNode(v) - head = head.next - return dummy.next +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def removeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]: + dummy = ListNode(inf, head) + cur = head + stk = [dummy] + while cur: + while stk[-1].val < cur.val: + stk.pop() + stk[-1].next = cur + stk.append(cur) + cur = cur.next + return dummy.next diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts index 04fdb565be8b5..fd149b2ca61e9 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts @@ -11,22 +11,14 @@ */ function removeNodes(head: ListNode | null): ListNode | null { - const nums = []; - for (; head; head = head.next) { - nums.push(head.val); - } - const stk: number[] = []; - for (const v of nums) { - while (stk.length && stk.at(-1)! < v) { + const dummy = new ListNode(Infinity, head); + const stk: ListNode[] = [dummy]; + for (let cur = head; cur; cur = cur.next) { + while (stk.at(-1)!.val < cur.val) { stk.pop(); } - stk.push(v); - } - const dummy = new ListNode(); - head = dummy; - for (const v of stk) { - head.next = new ListNode(v); - head = head.next; + stk.at(-1)!.next = cur; + stk.push(cur); } return dummy.next; } diff --git a/solution/2800-2899/2806.Account Balance After Rounded Purchase/README_EN.md b/solution/2800-2899/2806.Account Balance After Rounded Purchase/README_EN.md index 89c6805e89053..e5a0172e00ed7 100644 --- a/solution/2800-2899/2806.Account Balance After Rounded Purchase/README_EN.md +++ b/solution/2800-2899/2806.Account Balance After Rounded Purchase/README_EN.md @@ -43,6 +43,12 @@ Hence, your account balance becomes 100 - 20 = 80. ## Solutions +**Solution 1: Enumeration + Simulation** + +We enumerate all multiples of 10 within the range $[0, 100]$, and find the one that is closest to `purchaseAmount`, denoted as $x$. The answer is $100 - x$. + +The time complexity is $O(1)$, and the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README.md b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README.md index 4d59b72ab73ec..03c21363c7bd8 100644 --- a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README.md +++ b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README.md @@ -54,9 +54,9 @@ **方法一:模拟** -我们用两个指针 $pre$ 和 $cur$ 分别指向当前遍历到的结点和下一个结点,那么我们只需要在 $pre$ 和 $cur$ 之间插入一个新的结点即可。因此,每次计算出 $pre$ 和 $cur$ 的最大公约数 $x$,然后在 $pre$ 和 $cur$ 之间插入一个值为 $x$ 的新结点,然后更新 $pre$ 和 $cur$ 即可。当 $cur$ 为空时,说明已经遍历完了链表,此时返回链表的头结点即可。 +我们用两个指针 $pre$ 和 $cur$ 分别指向当前遍历到的结点和下一个结点,那么我们只需要在 $pre$ 和 $cur$ 之间插入一个新的结点即可。因此,每次计算出 $pre$ 和 $cur$ 的最大公约数 $x$,然后在 $pre$ 和 $cur$ 之间插入一个值为 $x$ 的新结点,然后更新 $pre = cur$,并且 $cur = cur.next$,继续遍历链表,直到 $cur$ 为空。 -时间复杂度 $O(n \times \log M)$,其中 $n$ 是链表的长度,而 $M$ 是链表中结点的最大值。空间复杂度 $O(1)$。 +时间复杂度 $O(n \times \log M)$,其中 $n$ 是链表的长度,而 $M$ 是链表中结点的最大值。忽略结果链表的空间消耗,空间复杂度 $O(1)$。 @@ -99,12 +99,10 @@ class Solution: */ class Solution { public ListNode insertGreatestCommonDivisors(ListNode head) { - ListNode pre = head, cur = head.next; - while (cur != null) { + for (ListNode pre = head, cur = head.next; cur != null; cur = cur.next) { int x = gcd(pre.val, cur.val); pre.next = new ListNode(x, cur); pre = cur; - cur = cur.next; } return head; } @@ -135,12 +133,10 @@ class Solution { public: ListNode* insertGreatestCommonDivisors(ListNode* head) { ListNode* pre = head; - ListNode* cur = head->next; - while (cur) { + for (ListNode* cur = head->next; cur; cur = cur->next) { int x = gcd(pre->val, cur->val); pre->next = new ListNode(x, cur); pre = cur; - cur = cur->next; } return head; } @@ -158,11 +154,10 @@ public: * } */ func insertGreatestCommonDivisors(head *ListNode) *ListNode { - pre, cur := head, head.Next - for cur != nil { + for pre, cur := head, head.Next; cur != nil; cur = cur.Next { x := gcd(pre.Val, cur.Val) pre.Next = &ListNode{x, cur} - pre, cur = cur, cur.Next + pre = cur } return head } @@ -191,13 +186,10 @@ func gcd(a, b int) int { */ function insertGreatestCommonDivisors(head: ListNode | null): ListNode | null { - let pre = head; - let cur = head.next; - while (cur) { + for (let pre = head, cur = head.next; cur; cur = cur.next) { const x = gcd(pre.val, cur.val); pre.next = new ListNode(x, cur); pre = cur; - cur = cur.next; } return head; } diff --git a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README_EN.md b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README_EN.md index 1937825613f7b..514c458e72816 100644 --- a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README_EN.md +++ b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/README_EN.md @@ -44,6 +44,12 @@ There are no pairs of adjacent nodes, so we return the initial linked list. ## Solutions +**Solution 1: Simulation** + +We use two pointers $pre$ and $cur$ to point to the current node and the next node respectively. We only need to insert a new node between $pre$ and $cur$. Therefore, each time we calculate the greatest common divisor $x$ of $pre$ and $cur$, we insert a new node with value $x$ between $pre$ and $cur$. Then we update $pre = cur$ and $cur = cur.next$, and continue to traverse the linked list until $cur$ is null. + +The time complexity is $O(n \times \log M)$, where $n$ is the length of the linked list, and $M$ is the maximum value of the nodes in the linked list. Ignoring the space consumption of the result linked list, the space complexity is $O(1)$. + ### **Python3** @@ -81,12 +87,10 @@ class Solution: */ class Solution { public ListNode insertGreatestCommonDivisors(ListNode head) { - ListNode pre = head, cur = head.next; - while (cur != null) { + for (ListNode pre = head, cur = head.next; cur != null; cur = cur.next) { int x = gcd(pre.val, cur.val); pre.next = new ListNode(x, cur); pre = cur; - cur = cur.next; } return head; } @@ -117,12 +121,10 @@ class Solution { public: ListNode* insertGreatestCommonDivisors(ListNode* head) { ListNode* pre = head; - ListNode* cur = head->next; - while (cur) { + for (ListNode* cur = head->next; cur; cur = cur->next) { int x = gcd(pre->val, cur->val); pre->next = new ListNode(x, cur); pre = cur; - cur = cur->next; } return head; } @@ -140,11 +142,10 @@ public: * } */ func insertGreatestCommonDivisors(head *ListNode) *ListNode { - pre, cur := head, head.Next - for cur != nil { + for pre, cur := head, head.Next; cur != nil; cur = cur.Next { x := gcd(pre.Val, cur.Val) pre.Next = &ListNode{x, cur} - pre, cur = cur, cur.Next + pre = cur } return head } @@ -173,13 +174,10 @@ func gcd(a, b int) int { */ function insertGreatestCommonDivisors(head: ListNode | null): ListNode | null { - let pre = head; - let cur = head.next; - while (cur) { + for (let pre = head, cur = head.next; cur; cur = cur.next) { const x = gcd(pre.val, cur.val); pre.next = new ListNode(x, cur); pre = cur; - cur = cur.next; } return head; } diff --git a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.cpp b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.cpp index fb8cf5af9c4bb..721cdef31870b 100644 --- a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.cpp +++ b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.cpp @@ -12,12 +12,10 @@ class Solution { public: ListNode* insertGreatestCommonDivisors(ListNode* head) { ListNode* pre = head; - ListNode* cur = head->next; - while (cur) { + for (ListNode* cur = head->next; cur; cur = cur->next) { int x = gcd(pre->val, cur->val); pre->next = new ListNode(x, cur); pre = cur; - cur = cur->next; } return head; } diff --git a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.go b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.go index 05e06322476e5..9ec7468dab34f 100644 --- a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.go +++ b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.go @@ -6,11 +6,10 @@ * } */ func insertGreatestCommonDivisors(head *ListNode) *ListNode { - pre, cur := head, head.Next - for cur != nil { + for pre, cur := head, head.Next; cur != nil; cur = cur.Next { x := gcd(pre.Val, cur.Val) pre.Next = &ListNode{x, cur} - pre, cur = cur, cur.Next + pre = cur } return head } diff --git a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.java b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.java index 2573409d74d56..532d0b86be33d 100644 --- a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.java +++ b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.java @@ -10,12 +10,10 @@ */ class Solution { public ListNode insertGreatestCommonDivisors(ListNode head) { - ListNode pre = head, cur = head.next; - while (cur != null) { + for (ListNode pre = head, cur = head.next; cur != null; cur = cur.next) { int x = gcd(pre.val, cur.val); pre.next = new ListNode(x, cur); pre = cur; - cur = cur.next; } return head; } diff --git a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.ts b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.ts index 20d23c4abdad8..ae7b6ad76be5d 100644 --- a/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.ts +++ b/solution/2800-2899/2807.Insert Greatest Common Divisors in Linked List/Solution.ts @@ -11,13 +11,10 @@ */ function insertGreatestCommonDivisors(head: ListNode | null): ListNode | null { - let pre = head; - let cur = head.next; - while (cur) { + for (let pre = head, cur = head.next; cur; cur = cur.next) { const x = gcd(pre.val, cur.val); pre.next = new ListNode(x, cur); pre = cur; - cur = cur.next; } return head; } diff --git a/solution/2800-2899/2808.Minimum Seconds to Equalize a Circular Array/README_EN.md b/solution/2800-2899/2808.Minimum Seconds to Equalize a Circular Array/README_EN.md index 8a640cfac2c4c..1fa7261f60a17 100644 --- a/solution/2800-2899/2808.Minimum Seconds to Equalize a Circular Array/README_EN.md +++ b/solution/2800-2899/2808.Minimum Seconds to Equalize a Circular Array/README_EN.md @@ -56,6 +56,16 @@ It can be proven that 2 seconds is the minimum amount of seconds needed for equa ## Solutions +**Solution 1: Enumeration** + +We assume that all elements eventually become $x$, and $x$ must be an element in the array. + +The number $x$ can expand one bit to the left and right every second. If there are multiple identical $x$, then the time required to expand the entire array depends on the maximum distance between two adjacent $x$. + +Therefore, we enumerate each element as the final $x$, calculate the maximum distance $t$ between two adjacent elements in each $x$, then the final answer is $\min\limits_{x \in nums} \left\lfloor \frac{t}{2} \right\rfloor$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array. + ### **Python3** diff --git a/solution/2800-2899/2809.Minimum Time to Make Array Sum At Most x/README_EN.md b/solution/2800-2899/2809.Minimum Time to Make Array Sum At Most x/README_EN.md index 049da84773fb2..495945b8cfb36 100644 --- a/solution/2800-2899/2809.Minimum Time to Make Array Sum At Most x/README_EN.md +++ b/solution/2800-2899/2809.Minimum Time to Make Array Sum At Most x/README_EN.md @@ -49,6 +49,35 @@ Now sum of nums1 = 4. It can be shown that these operations are optimal, so we r ## Solutions +**Solution 1: Sorting + Dynamic Programming** + +We notice that if we operate on the same number multiple times, only the last operation is meaningful, and the rest of the operations on that number will only increase the other numbers. Therefore, we operate on each number at most once, that is to say, the number of operations is within $[0,..n]$. + +Let's assume that we have performed $j$ operations, and the indices of the numbers operated on are $i_1, i_2, \cdots, i_j$. For these $j$ operations, the value that each operation can reduce the sum of array elements is: + +$$ +\begin{aligned} +& d_1 = nums_1[i_1] + nums_2[i_1] \times 1 \\ +& d_2 = nums_1[i_2] + nums_2[i_2] \times 2 \\ +& \cdots \\ +& d_j = nums_1[i_j] + nums_2[i_j] \times j +\end{aligned} +$$ + +From a greedy perspective, in order to maximize the reduction of the sum of array elements, we should let the larger elements in $nums_2$ be operated on as late as possible. Therefore, we can sort $nums_1$ and $nums_2$ in ascending order of the element values in $nums_2$. + +Next, we consider the implementation of dynamic programming. We use $f[i][j]$ to represent the maximum value that can reduce the sum of array elements for the first $i$ elements of the array $nums_1$ with $j$ operations. We can get the following state transition equation: + +$$ +f[i][j] = \max \{f[i-1][j], f[i-1][j-1] + nums_1[i] + nums_2[i] \times j\} +$$ + +Finally, we enumerate $j$ and find the smallest $j$ that satisfies $s_1 + s_2 \times j - f[n][j] \le x$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$, where $n$ is the length of the array. + +We notice that the state $f[i][j]$ is only related to $f[i-1][j]$ and $f[i-1][j-1]$, so we can optimize the first dimension and reduce the space complexity to $O(n)$. + ### **Python3** diff --git a/solution/2800-2899/2810.Faulty Keyboard/README_EN.md b/solution/2800-2899/2810.Faulty Keyboard/README_EN.md index d805c4efe4a07..fd3260352ffe8 100644 --- a/solution/2800-2899/2810.Faulty Keyboard/README_EN.md +++ b/solution/2800-2899/2810.Faulty Keyboard/README_EN.md @@ -53,6 +53,16 @@ Therefore, we return "ponter". ## Solutions +**Solution 1: Simulation** + +We directly simulate the keyboard input process, using a character array $t$ to record the text on the screen, initially $t$ is empty. + +For each character $c$ in string $s$, if $c$ is not the character $'i'$, then we add $c$ to the end of $t$; otherwise, we reverse all characters in $t$. + +The final answer is the string composed of characters in $t$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$, where $n$ is the length of string $s$. + ### **Python3** diff --git a/solution/2800-2899/2811.Check if it is Possible to Split Array/README.md b/solution/2800-2899/2811.Check if it is Possible to Split Array/README.md index 646901d137e06..50e27508f2383 100644 --- a/solution/2800-2899/2811.Check if it is Possible to Split Array/README.md +++ b/solution/2800-2899/2811.Check if it is Possible to Split Array/README.md @@ -94,7 +94,7 @@ > 📢 注意,当 `nums.length <= 2` 时,无需进行操作。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。 +时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。 diff --git a/solution/2800-2899/2811.Check if it is Possible to Split Array/README_EN.md b/solution/2800-2899/2811.Check if it is Possible to Split Array/README_EN.md index 3a6dcfe787776..86563488b3799 100644 --- a/solution/2800-2899/2811.Check if it is Possible to Split Array/README_EN.md +++ b/solution/2800-2899/2811.Check if it is Possible to Split Array/README_EN.md @@ -51,6 +51,34 @@ ## Solutions +**Solution 1: Memoization Search** + +First, we preprocess to get the prefix sum array $s$, where $s[i]$ represents the sum of the first $i$ elements of the array $nums$. + +Next, we design a function $dfs(i, j)$, which represents whether there is a way to split the index range $[i, j]$ of the array $nums$ that meets the conditions. If it exists, return `true`, otherwise return `false`. + +The calculation process of the function $dfs(i, j)$ is as follows: + +If $i = j$, then there is only one element, no need to split, return `true`; + +Otherwise, we enumerate the split point $k$, where $k \in [i, j]$, if the following conditions are met, then it can be split into two subarrays $nums[i,.. k]$ and $nums[k + 1,.. j]$: + +- The subarray $nums[i,..k]$ has only one element, or the sum of the elements of the subarray $nums[i,..k]$ is greater than or equal to $m$; +- The subarray $nums[k + 1,..j]$ has only one element, or the sum of the elements of the subarray $nums[k + 1,..j]$ is greater than or equal to $m$; +- Both $dfs(i, k)$ and $dfs(k + 1, j)$ are `true`. + +To avoid repeated calculations, we use the method of memoization search, and use a two-dimensional array $f$ to record all the return values of $dfs(i, j)$, where $f[i][j]$ represents the return value of $dfs(i, j)$. + +The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$, where $n$ is the length of the array $nums$. + +**Solution 2: Quick Thinking** + +No matter how you operate, there will always be a `length == 2` subarray left in the end. Since there are no negative numbers in the elements, as the split operation proceeds, the length and sum of the subarray will gradually decrease. The sum of other `length > 2` subarrays must be larger than the sum of this subarray. Therefore, we only need to consider whether there is a `length == 2` subarray with a sum greater than or equal to `m`. + +> 📢 Note that when `nums.length <= 2`, no operation is needed. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + ### **Python3** diff --git a/solution/2900-2999/2985.Calculate Compressed Mean/README.md b/solution/2900-2999/2985.Calculate Compressed Mean/README.md index db35d9c8a6333..4ebe00dd687a5 100644 --- a/solution/2900-2999/2985.Calculate Compressed Mean/README.md +++ b/solution/2900-2999/2985.Calculate Compressed Mean/README.md @@ -56,6 +56,10 @@ The calculation is as follows: +**方法一:求和** + +我们使用 `SUM` 函数求出总的商品数量和总的订单数,然后相除,得到平均值,最后使用 `ROUND` 函数保留两位小数即可。 + ### **SQL** diff --git a/solution/2900-2999/2985.Calculate Compressed Mean/README_EN.md b/solution/2900-2999/2985.Calculate Compressed Mean/README_EN.md index bcd79bd720e27..42ad8a05024d4 100644 --- a/solution/2900-2999/2985.Calculate Compressed Mean/README_EN.md +++ b/solution/2900-2999/2985.Calculate Compressed Mean/README_EN.md @@ -52,6 +52,10 @@ The calculation is as follows: ## Solutions +**Solution 1: Summation** + +We use the `SUM` function to calculate the total quantity of products and the total number of orders, then divide the total quantity by the total number of orders to get the average. Finally, we use the `ROUND` function to round the result to two decimal places. + ### **SQL** diff --git a/solution/2900-2999/2987.Find Expensive Cities/README.md b/solution/2900-2999/2987.Find Expensive Cities/README.md index 830e08e2f7daa..8c1df66e3722f 100644 --- a/solution/2900-2999/2987.Find Expensive Cities/README.md +++ b/solution/2900-2999/2987.Find Expensive Cities/README.md @@ -68,6 +68,10 @@ Only Chicago and Los Angeles have average home prices exceeding the national ave +**方法一:分组聚合 + 子查询** + +我们将 `Listings` 表按照 `city` 分组,然后计算每个城市的平均房价,最后筛选出平均房价大于全国平均房价的城市即可。 + ### **SQL** diff --git a/solution/2900-2999/2987.Find Expensive Cities/README_EN.md b/solution/2900-2999/2987.Find Expensive Cities/README_EN.md index 3a156e76b097c..399f28b3e7abb 100644 --- a/solution/2900-2999/2987.Find Expensive Cities/README_EN.md +++ b/solution/2900-2999/2987.Find Expensive Cities/README_EN.md @@ -64,6 +64,10 @@ Only Chicago and Los Angeles have average home prices exceeding the national ave ## Solutions +**Solution 1: Grouping Aggregation + Subquery** + +We group the `Listings` table by `city`, then calculate the average house price for each city, and finally filter out the cities where the average house price is greater than the national average house price. + ### **SQL** diff --git a/solution/2900-2999/2988.Manager of the Largest Department/README.md b/solution/2900-2999/2988.Manager of the Largest Department/README.md index a33764cba0c50..ed583464591d5 100644 --- a/solution/2900-2999/2988.Manager of the Largest Department/README.md +++ b/solution/2900-2999/2988.Manager of the Largest Department/README.md @@ -65,6 +65,10 @@ Output table is ordered by dep_id in ascending order. +**方法一:分组 + 等值连接 + 子查询** + +我们可以先统计每个部门的员工数量,记为表 `T`,然后我们将 `T` 与 `Employees` 表进行连接,连接条件为 `T.dep_id = Employees.dep_id`,并且 `Employees.position = 'Manager'`,这样就可以得到每个部门的经理,最后我们再筛选出员工数量最多的部门即可。 + ### **SQL** diff --git a/solution/2900-2999/2988.Manager of the Largest Department/README_EN.md b/solution/2900-2999/2988.Manager of the Largest Department/README_EN.md index 2b8e5cf25b915..4511ca3142c1f 100644 --- a/solution/2900-2999/2988.Manager of the Largest Department/README_EN.md +++ b/solution/2900-2999/2988.Manager of the Largest Department/README_EN.md @@ -61,6 +61,10 @@ Output table is ordered by dep_id in ascending order. ## Solutions +**Solution 1: Grouping + Equi-Join + Subquery** + +We can first count the number of employees in each department, denoted as table `T`. Then we join `T` with the `Employees` table, with the join condition being `T.dep_id = Employees.dep_id` and `Employees.position = 'Manager'`. This way, we can get the manager of each department. Finally, we filter out the department with the most employees. + ### **SQL**