From f597f0a30b11a988446bdb1329ca2ef3843434cb Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 3 Jan 2024 08:01:49 +0800 Subject: [PATCH] feat: add solutions to lc problems: No.2485~2487 --- .../2485.Find the Pivot Integer/README_EN.md | 28 ++++ .../README.md | 29 +++- .../README_EN.md | 33 +++- .../Solution.py | 21 ++- .../Solution.ts | 13 ++ .../README.md | 150 ++++++++++++++++++ .../README_EN.md | 150 ++++++++++++++++++ 7 files changed, 402 insertions(+), 22 deletions(-) create mode 100644 solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts diff --git a/solution/2400-2499/2485.Find the Pivot Integer/README_EN.md b/solution/2400-2499/2485.Find the Pivot Integer/README_EN.md index ffc2625458cf4..9eca90b7888ae 100644 --- a/solution/2400-2499/2485.Find the Pivot Integer/README_EN.md +++ b/solution/2400-2499/2485.Find the Pivot Integer/README_EN.md @@ -46,6 +46,34 @@ ## Solutions +**Solution 1: Enumeration** + +We can directly enumerate $x$ in the range of $[1,..n]$, and check whether the following equation holds. If it holds, then $x$ is the pivot integer, and we can directly return $x$. + +$$ +(1 + x) \times x = (x + n) \times (n - x + 1) +$$ + +The time complexity is $O(n)$, where $n$ is the given positive integer $n$. The space complexity is $O(1)$. + +**Solution 2: Mathematics** + +We can transform the above equation to get: + +$$ +n \times (n + 1) = 2 \times x^2 +$$ + +That is: + +$$ +x = \sqrt{\frac{n \times (n + 1)}{2}} +$$ + +If $x$ is an integer, then $x$ is the pivot integer, otherwise there is no pivot integer. + +The time complexity is $O(1)$, and the space complexity is $O(1)$. + ### **Python3** diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md index 9ddda45d7a0f5..3b81f1184c580 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README.md @@ -57,7 +57,7 @@ **方法一:双指针** -定义两个指针 $i$ 和 $j$,分别指向字符串 $s$ 和 $t$ 的首字符。遍历字符串 $t$,当 $s[i] \neq t[j]$ 时,指针 $i$ 后移,直到 $s[i] = t[j]$ 或者 $i$ 到达字符串 $s$ 的末尾。如果 $i$ 到达字符串 $s$ 的末尾,说明 $t$ 中的字符 $t[j]$ 无法在 $s$ 中找到对应的字符,返回 $t$ 中剩余的字符数。否则,将指针 $i$ 和 $j$ 同时后移,继续遍历字符串 $t$。 +我们定义两个指针 $i$ 和 $j$,分别指向字符串 $s$ 和 $t$ 的首字符。遍历字符串 $t$,当 $s[i] \neq t[j]$ 时,指针 $i$ 后移,直到 $s[i] = t[j]$ 或者 $i$ 到达字符串 $s$ 的末尾。如果 $i$ 到达字符串 $s$ 的末尾,说明 $t$ 中的字符 $t[j]$ 无法在 $s$ 中找到对应的字符,返回 $t$ 中剩余的字符数。否则,将指针 $i$ 和 $j$ 同时后移,继续遍历字符串 $t$。 时间复杂度 $(m + n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是字符串 $s$ 和 $t$ 的长度。 @@ -70,13 +70,12 @@ ```python class Solution: def appendCharacters(self, s: str, t: str) -> int: - m, n = len(s), len(t) - i = 0 - for j in range(n): - while i < m and s[i] != t[j]: + i, m = 0, len(s) + for j, c in enumerate(t): + while i < m and s[i] != c: i += 1 if i == m: - return n - j + return len(t) - j i += 1 return 0 ``` @@ -139,6 +138,24 @@ func appendCharacters(s string, t string) int { } ``` +### **TypeScript** + +```ts +function appendCharacters(s: string, t: string): number { + const [m, n] = [s.length, t.length]; + for (let i = 0, j = 0; j < n; ++j) { + while (i < m && s[i] !== t[j]) { + ++i; + } + if (i === m) { + return n - j; + } + ++i; + } + return 0; +} +``` + ### **...** ``` diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md index c5779c76fcbf2..58920f972b2e2 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/README_EN.md @@ -49,6 +49,12 @@ It can be shown that appending any 4 characters to the end of s will never make ## Solutions +**Solution 1: Two Pointers** + +We define two pointers $i$ and $j$, pointing to the first characters of strings $s$ and $t$ respectively. We traverse string $t$, when $s[i] \neq t[j]$, we move pointer $i$ forward until $s[i] = t[j]$ or $i$ reaches the end of string $s$. If $i$ reaches the end of string $s$, it means that the character $t[j]$ in $t$ cannot find the corresponding character in $s$, so we return the remaining number of characters in $t$. Otherwise, we move both pointers $i$ and $j$ forward and continue to traverse string $t$. + +The time complexity is $O(m + n)$, and the space complexity is $O(1)$. Where $m$ and $n$ are the lengths of strings $s$ and $t$ respectively. + ### **Python3** @@ -56,13 +62,12 @@ It can be shown that appending any 4 characters to the end of s will never make ```python class Solution: def appendCharacters(self, s: str, t: str) -> int: - m, n = len(s), len(t) - i = 0 - for j in range(n): - while i < m and s[i] != t[j]: + i, m = 0, len(s) + for j, c in enumerate(t): + while i < m and s[i] != c: i += 1 if i == m: - return n - j + return len(t) - j i += 1 return 0 ``` @@ -123,6 +128,24 @@ func appendCharacters(s string, t string) int { } ``` +### **TypeScript** + +```ts +function appendCharacters(s: string, t: string): number { + const [m, n] = [s.length, t.length]; + for (let i = 0, j = 0; j < n; ++j) { + while (i < m && s[i] !== t[j]) { + ++i; + } + if (i === m) { + return n - j; + } + ++i; + } + return 0; +} +``` + ### **...** ``` diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py index 1cebb82558e7f..d23af9b595e97 100644 --- a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.py @@ -1,11 +1,10 @@ -class Solution: - def appendCharacters(self, s: str, t: str) -> int: - m, n = len(s), len(t) - i = 0 - for j in range(n): - while i < m and s[i] != t[j]: - i += 1 - if i == m: - return n - j - i += 1 - return 0 +class Solution: + def appendCharacters(self, s: str, t: str) -> int: + i, m = 0, len(s) + for j, c in enumerate(t): + while i < m and s[i] != c: + i += 1 + if i == m: + return len(t) - j + i += 1 + return 0 diff --git a/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts new file mode 100644 index 0000000000000..349b20c8889bd --- /dev/null +++ b/solution/2400-2499/2486.Append Characters to String to Make Subsequence/Solution.ts @@ -0,0 +1,13 @@ +function appendCharacters(s: string, t: string): number { + const [m, n] = [s.length, t.length]; + for (let i = 0, j = 0; j < n; ++j) { + while (i < m && s[i] !== t[j]) { + ++i; + } + if (i === m) { + return n - j; + } + ++i; + } + return 0; +} 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 17d8d57f4a7a5..16a68fe38c876 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 @@ -56,6 +56,12 @@ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是链表的长度。 +我们也可以不使用数组 $nums$,直接遍历链表,维护一个从栈底到栈顶单调递减的栈 $stk$,如果当前元素比栈顶元素大,则将栈顶元素出栈,直到当前元素小于等于栈顶元素。然后,如果栈不为空,则将栈顶元素的 $next$ 指针指向当前元素,否则将答案链表的虚拟头节点的 $next$ 指针指向当前元素。最后,将当前元素入栈,继续遍历链表。 + +遍历结束后,将虚拟头节点的 $next$ 指针作为答案返回。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是链表的长度。 + ### **Python3** @@ -87,6 +93,29 @@ class Solution: return dummy.next ``` +```python +# 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(next=head) + cur = head + stk = [] + while cur: + while stk and stk[-1].val < cur.val: + stk.pop() + if stk: + stk[-1].next = cur + else: + dummy.next = cur + stk.append(cur) + cur = cur.next + return dummy.next +``` + ### **Java** @@ -127,6 +156,37 @@ class Solution { } ``` +```java +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode removeNodes(ListNode head) { + ListNode dummy = new ListNode(0, head); + Deque stk = new ArrayDeque<>(); + for (ListNode cur = head; cur != null; cur = cur.next) { + while (!stk.isEmpty() && stk.peekLast().val < cur.val) { + stk.pollLast(); + } + if (!stk.isEmpty()) { + stk.peekLast().next = cur; + } else { + dummy.next = cur; + } + stk.offerLast(cur); + } + return dummy.next; + } +} +``` + ### **C++** ```cpp @@ -166,6 +226,39 @@ public: }; ``` +```cpp +/** + * 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(0, head); + ListNode* cur = head; + vector stk; + for (ListNode* cur = head; cur; cur = cur->next) { + while (stk.size() && stk.back()->val < cur->val) { + stk.pop_back(); + } + if (stk.size()) { + stk.back()->next = cur; + } else { + dummy->next = cur; + } + stk.push_back(cur); + } + return dummy->next; + } +}; +``` + ### **Go** ```go @@ -199,6 +292,32 @@ func removeNodes(head *ListNode) *ListNode { } ``` +```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func removeNodes(head *ListNode) *ListNode { + dummy := &ListNode{Next: head} + stk := []*ListNode{} + for cur := head; cur != nil; cur = cur.Next { + for len(stk) > 0 && 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 = append(stk, cur) + } + return dummy.Next +} +``` + ### **TypeScript** ```ts @@ -236,6 +355,37 @@ function removeNodes(head: ListNode | null): ListNode | null { } ``` +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function removeNodes(head: ListNode | null): ListNode | null { + const dummy = new ListNode(0, head); + const stk: ListNode[] = []; + for (let cur = head; cur; cur = cur.next) { + while (stk.length && stk.at(-1)!.val < cur.val) { + stk.pop(); + } + if (stk.length) { + stk.at(-1)!.next = cur; + } else { + dummy.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 9a50373f14f20..1f27507a91ba8 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 @@ -48,6 +48,12 @@ Finally, we construct the resulting linked list from the bottom to the top of th The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the linked list. +We can also directly traverse the linked list without using the array $nums$, maintaining a stack $stk$ that is monotonically decreasing from the bottom to the top. If the current element is larger than the top element of the stack, we pop the top element of the stack until the current element is less than or equal to the top element. Then, if the stack is not empty, we set the $next$ pointer of the top element of the stack to the current element. Otherwise, we set the $next$ pointer of the dummy head node of the answer linked list to the current element. Finally, we push the current element into the stack and continue to traverse the linked list. + +After the traversal, we return the $next$ pointer of the dummy head node as the answer. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the linked list. + ### **Python3** @@ -77,6 +83,29 @@ class Solution: return dummy.next ``` +```python +# 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(next=head) + cur = head + stk = [] + while cur: + while stk and stk[-1].val < cur.val: + stk.pop() + if stk: + stk[-1].next = cur + else: + dummy.next = cur + stk.append(cur) + cur = cur.next + return dummy.next +``` + ### **Java** ```java @@ -115,6 +144,37 @@ class Solution { } ``` +```java +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode removeNodes(ListNode head) { + ListNode dummy = new ListNode(0, head); + Deque stk = new ArrayDeque<>(); + for (ListNode cur = head; cur != null; cur = cur.next) { + while (!stk.isEmpty() && stk.peekLast().val < cur.val) { + stk.pollLast(); + } + if (!stk.isEmpty()) { + stk.peekLast().next = cur; + } else { + dummy.next = cur; + } + stk.offerLast(cur); + } + return dummy.next; + } +} +``` + ### **C++** ```cpp @@ -154,6 +214,39 @@ public: }; ``` +```cpp +/** + * 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(0, head); + ListNode* cur = head; + vector stk; + for (ListNode* cur = head; cur; cur = cur->next) { + while (stk.size() && stk.back()->val < cur->val) { + stk.pop_back(); + } + if (stk.size()) { + stk.back()->next = cur; + } else { + dummy->next = cur; + } + stk.push_back(cur); + } + return dummy->next; + } +}; +``` + ### **Go** ```go @@ -187,6 +280,32 @@ func removeNodes(head *ListNode) *ListNode { } ``` +```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func removeNodes(head *ListNode) *ListNode { + dummy := &ListNode{Next: head} + stk := []*ListNode{} + for cur := head; cur != nil; cur = cur.Next { + for len(stk) > 0 && 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 = append(stk, cur) + } + return dummy.Next +} +``` + ### **TypeScript** ```ts @@ -224,6 +343,37 @@ function removeNodes(head: ListNode | null): ListNode | null { } ``` +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function removeNodes(head: ListNode | null): ListNode | null { + const dummy = new ListNode(0, head); + const stk: ListNode[] = []; + for (let cur = head; cur; cur = cur.next) { + while (stk.length && stk.at(-1)!.val < cur.val) { + stk.pop(); + } + if (stk.length) { + stk.at(-1)!.next = cur; + } else { + dummy.next = cur; + } + stk.push(cur); + } + return dummy.next; +} +``` + ### **...** ```