From 2f1324a006adadffccfebfd9ee3aa2a006c1af84 Mon Sep 17 00:00:00 2001
From: Surav Shrestha <98219089+suravshresth@users.noreply.github.com>
Date: Tue, 12 Dec 2023 06:19:30 +0545
Subject: [PATCH 1/5] docs: fix typos in lcci No.05.02 (#2086)
Co-authored-by: Surav Shrestha
---
lcci/05.02.Binary Number to String/README_EN.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lcci/05.02.Binary Number to String/README_EN.md b/lcci/05.02.Binary Number to String/README_EN.md
index 61e8d7b968e81..9911a2ec5637e 100644
--- a/lcci/05.02.Binary Number to String/README_EN.md
+++ b/lcci/05.02.Binary Number to String/README_EN.md
@@ -1,6 +1,6 @@
-# [05.02. Bianry Number to String](https://leetcode.cn/problems/bianry-number-to-string-lcci)
+# [05.02. Binary Number to String](https://leetcode.cn/problems/bianry-number-to-string-lcci)
-[中文文档](/lcci/05.02.Bianry%20Number%20to%20String/README.md)
+[中文文档](/lcci/05.02.Binary%20Number%20to%20String/README.md)
## Description
@@ -25,7 +25,7 @@
Note:
- - This two charaters "0." should be counted into 32 characters.
+ - This two characters "0." should be counted into 32 characters.
## Solutions
From 06fff4b9e276a349585623e5e0e787944919e4ba Mon Sep 17 00:00:00 2001
From: Libin YANG
Date: Tue, 12 Dec 2023 09:46:34 +0800
Subject: [PATCH 2/5] feat: add solutions to lc problem: No.2454 (#2087)
No.2454.Next Greater Element IV
---
.../2454.Next Greater Element IV/README.md | 768 ++++++++++++++++--
.../2454.Next Greater Element IV/README_EN.md | 766 +++++++++++++++--
.../2454.Next Greater Element IV/Solution.cpp | 45 +-
.../2454.Next Greater Element IV/Solution.go | 34 -
.../Solution.java | 41 +-
.../2454.Next Greater Element IV/Solution.py | 29 +-
.../2454.Next Greater Element IV/Solution.ts | 661 +++++++++++++++
7 files changed, 2111 insertions(+), 233 deletions(-)
delete mode 100644 solution/2400-2499/2454.Next Greater Element IV/Solution.go
create mode 100644 solution/2400-2499/2454.Next Greater Element IV/Solution.ts
diff --git a/solution/2400-2499/2454.Next Greater Element IV/README.md b/solution/2400-2499/2454.Next Greater Element IV/README.md
index 05da24c904279..caf0a7a09dfd8 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/README.md
+++ b/solution/2400-2499/2454.Next Greater Element IV/README.md
@@ -62,15 +62,13 @@
-**方法一:单调栈 + 优先队列(小根堆)**
+**方法一:排序 + 有序集合**
-求下一个更大的元素,可以使用单调栈来实现。我们维护一个栈,然后从左到右遍历数组,如果栈顶元素小于当前元素,则当前元素就是栈顶元素的下一个更大的元素。
+我们可以将数组中的元素转成二元组 $(x, i)$,其中 $x$ 为元素的值,$i$ 为元素的下标。然后按照元素的值从大到小排序。
-这道题的变形是求下一个更大的元素的下一个更大的元素,即第二大的元素。我们观察单调栈求下一个更大元素的过程,每次出栈时,栈顶元素找到了下一个更大的元素,但我们是要为栈顶元素找到第二个更大的元素。次数,我们可以将栈顶元素出栈,放到一个优先队列(小根堆)中。每次遍历数组元素时,先判断当前元素是否大于优先队列的堆顶元素,如果大于,说明堆顶元素找打了第二个更大的元素,更新答案数组,然后弹出堆顶元素,继续判断当前元素是否大于优先队列的堆顶元素,直到堆为空或者当前元素不大于堆顶元素。
+接下来,我们遍历排序后的数组,维护一个有序集合,其中存储的是元素的下标。当我们遍历到元素 $(x, i)$ 时,所有大于 $x$ 的元素的下标都已经在有序集合中了。我们只需要在有序集合中,找到 $i$ 的下下一个元素的下标 $j$,那么 $j$ 对应的元素就是 $x$ 的第二大元素。然后,我们将 $i$ 加入到有序集合中。继续遍历下一个元素。
-接着,执行单调栈的相关操作,弹出栈顶元素后,放入到优先队列中。
-
-时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
@@ -79,18 +77,21 @@
```python
+from sortedcontainers import SortedList
+
+
class Solution:
def secondGreaterElement(self, nums: List[int]) -> List[int]:
- stk = []
- q = []
- ans = [-1] * len(nums)
- for i, v in enumerate(nums):
- while q and q[0][0] < v:
- ans[q[0][1]] = v
- heappop(q)
- while stk and nums[stk[-1]] < v:
- heappush(q, (nums[stk[-1]], stk.pop()))
- stk.append(i)
+ arr = [(x, i) for i, x in enumerate(nums)]
+ arr.sort(key=lambda x: -x[0])
+ sl = SortedList()
+ n = len(nums)
+ ans = [-1] * n
+ for _, i in arr:
+ j = sl.bisect_right(i)
+ if j + 1 < len(sl):
+ ans[i] = nums[sl[j + 1]]
+ sl.add(i)
return ans
```
@@ -101,21 +102,22 @@ class Solution:
```java
class Solution {
public int[] secondGreaterElement(int[] nums) {
- Deque stk = new ArrayDeque<>();
- PriorityQueue q = new PriorityQueue<>((a, b) -> a[0] - b[0]);
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans, -1);
+ int[][] arr = new int[n][0];
for (int i = 0; i < n; ++i) {
- int v = nums[i];
- while (!q.isEmpty() && q.peek()[0] < v) {
- ans[q.peek()[1]] = v;
- q.poll();
- }
- while (!stk.isEmpty() && nums[stk.peek()] < v) {
- q.offer(new int[] {nums[stk.peek()], stk.pop()});
+ arr[i] = new int[] {nums[i], i};
+ }
+ Arrays.sort(arr, (a, b) -> b[0] - a[0]);
+ TreeSet ts = new TreeSet<>();
+ for (int[] pair : arr) {
+ int i = pair[1];
+ Integer j = ts.higher(i);
+ if (j != null && ts.higher(j) != null) {
+ ans[i] = nums[ts.higher(j)];
}
- stk.push(i);
+ ts.add(i);
}
return ans;
}
@@ -125,75 +127,693 @@ class Solution {
### **C++**
```cpp
-using pii = pair;
-
class Solution {
public:
vector secondGreaterElement(vector& nums) {
- stack stk;
- priority_queue, greater> q;
int n = nums.size();
vector ans(n, -1);
+ vector> arr(n);
for (int i = 0; i < n; ++i) {
- int v = nums[i];
- while (!q.empty() && q.top().first < v) {
- ans[q.top().second] = v;
- q.pop();
- }
- while (!stk.empty() && nums[stk.top()] < v) {
- q.push({nums[stk.top()], stk.top()});
- stk.pop();
+ arr[i] = {-nums[i], i};
+ }
+ sort(arr.begin(), arr.end());
+ set ts;
+ for (auto& [_, i] : arr) {
+ auto it = ts.upper_bound(i);
+ if (it != ts.end() && ts.upper_bound(*it) != ts.end()) {
+ ans[i] = nums[*ts.upper_bound(*it)];
}
- stk.push(i);
+ ts.insert(i);
}
return ans;
}
};
```
-### **Go**
-
-```go
-func secondGreaterElement(nums []int) []int {
- stk := []int{}
- q := hp{}
- n := len(nums)
- ans := make([]int, n)
- for i := range ans {
- ans[i] = -1
- }
- for i, v := range nums {
- for len(q) > 0 && q[0].v < v {
- ans[q[0].i] = v
- heap.Pop(&q)
- }
- for len(stk) > 0 && nums[stk[len(stk)-1]] < v {
- heap.Push(&q, pair{nums[stk[len(stk)-1]], stk[len(stk)-1]})
- stk = stk[:len(stk)-1]
- }
- stk = append(stk, i)
- }
- return ans
+### **TypeScript**
+
+```ts
+function secondGreaterElement(nums: number[]): number[] {
+ const n = nums.length;
+ const arr: number[][] = [];
+ for (let i = 0; i < n; ++i) {
+ arr.push([nums[i], i]);
+ }
+ arr.sort((a, b) => b[0] - a[0]);
+ const ans = Array(n).fill(-1);
+ const ts = new TreeSet();
+ for (const [_, i] of arr) {
+ let j = ts.higher(i);
+ if (j !== undefined) {
+ j = ts.higher(j);
+ if (j !== undefined) {
+ ans[i] = nums[j];
+ }
+ }
+ ts.add(i);
+ }
+ return ans;
}
-type pair struct{ v, i int }
+type Compare = (lhs: T, rhs: T) => number;
+
+class RBTreeNode {
+ data: T;
+ count: number;
+ left: RBTreeNode | null;
+ right: RBTreeNode | null;
+ parent: RBTreeNode | null;
+ color: number;
+ constructor(data: T) {
+ this.data = data;
+ this.left = this.right = this.parent = null;
+ this.color = 0;
+ this.count = 1;
+ }
+
+ sibling(): RBTreeNode | null {
+ if (!this.parent) return null; // sibling null if no parent
+ return this.isOnLeft() ? this.parent.right : this.parent.left;
+ }
-type hp []pair
+ isOnLeft(): boolean {
+ return this === this.parent!.left;
+ }
-func (h hp) Len() int { return len(h) }
-func (h hp) Less(i, j int) bool {
- a, b := h[i], h[j]
- return a.v < b.v
+ hasRedChild(): boolean {
+ return (
+ Boolean(this.left && this.left.color === 0) ||
+ Boolean(this.right && this.right.color === 0)
+ );
+ }
}
-func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
-func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
-func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
-```
-### **TypeScript**
+class RBTree {
+ root: RBTreeNode | null;
+ lt: (l: T, r: T) => boolean;
+ constructor(compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0)) {
+ this.root = null;
+ this.lt = (l: T, r: T) => compare(l, r) < 0;
+ }
-```ts
+ rotateLeft(pt: RBTreeNode): void {
+ const right = pt.right!;
+ pt.right = right.left;
+
+ if (pt.right) pt.right.parent = pt;
+ right.parent = pt.parent;
+
+ if (!pt.parent) this.root = right;
+ else if (pt === pt.parent.left) pt.parent.left = right;
+ else pt.parent.right = right;
+
+ right.left = pt;
+ pt.parent = right;
+ }
+
+ rotateRight(pt: RBTreeNode): void {
+ const left = pt.left!;
+ pt.left = left.right;
+
+ if (pt.left) pt.left.parent = pt;
+ left.parent = pt.parent;
+
+ if (!pt.parent) this.root = left;
+ else if (pt === pt.parent.left) pt.parent.left = left;
+ else pt.parent.right = left;
+
+ left.right = pt;
+ pt.parent = left;
+ }
+
+ swapColor(p1: RBTreeNode, p2: RBTreeNode): void {
+ const tmp = p1.color;
+ p1.color = p2.color;
+ p2.color = tmp;
+ }
+
+ swapData(p1: RBTreeNode, p2: RBTreeNode): void {
+ const tmp = p1.data;
+ p1.data = p2.data;
+ p2.data = tmp;
+ }
+
+ fixAfterInsert(pt: RBTreeNode): void {
+ let parent = null;
+ let grandParent = null;
+
+ while (pt !== this.root && pt.color !== 1 && pt.parent?.color === 0) {
+ parent = pt.parent;
+ grandParent = pt.parent.parent;
+
+ /* Case : A
+ Parent of pt is left child of Grand-parent of pt */
+ if (parent === grandParent?.left) {
+ const uncle = grandParent.right;
+
+ /* Case : 1
+ The uncle of pt is also red
+ Only Recoloring required */
+ if (uncle && uncle.color === 0) {
+ grandParent.color = 0;
+ parent.color = 1;
+ uncle.color = 1;
+ pt = grandParent;
+ } else {
+ /* Case : 2
+ pt is right child of its parent
+ Left-rotation required */
+ if (pt === parent.right) {
+ this.rotateLeft(parent);
+ pt = parent;
+ parent = pt.parent;
+ }
+
+ /* Case : 3
+ pt is left child of its parent
+ Right-rotation required */
+ this.rotateRight(grandParent);
+ this.swapColor(parent!, grandParent);
+ pt = parent!;
+ }
+ } else {
+ /* Case : B
+ Parent of pt is right child of Grand-parent of pt */
+ const uncle = grandParent!.left;
+
+ /* Case : 1
+ The uncle of pt is also red
+ Only Recoloring required */
+ if (uncle != null && uncle.color === 0) {
+ grandParent!.color = 0;
+ parent.color = 1;
+ uncle.color = 1;
+ pt = grandParent!;
+ } else {
+ /* Case : 2
+ pt is left child of its parent
+ Right-rotation required */
+ if (pt === parent.left) {
+ this.rotateRight(parent);
+ pt = parent;
+ parent = pt.parent;
+ }
+
+ /* Case : 3
+ pt is right child of its parent
+ Left-rotation required */
+ this.rotateLeft(grandParent!);
+ this.swapColor(parent!, grandParent!);
+ pt = parent!;
+ }
+ }
+ }
+ this.root!.color = 1;
+ }
+ delete(val: T): boolean {
+ const node = this.find(val);
+ if (!node) return false;
+ node.count--;
+ if (!node.count) this.deleteNode(node);
+ return true;
+ }
+
+ deleteAll(val: T): boolean {
+ const node = this.find(val);
+ if (!node) return false;
+ this.deleteNode(node);
+ return true;
+ }
+
+ deleteNode(v: RBTreeNode): void {
+ const u = BSTreplace(v);
+
+ // True when u and v are both black
+ const uvBlack = (u === null || u.color === 1) && v.color === 1;
+ const parent = v.parent!;
+
+ if (!u) {
+ // u is null therefore v is leaf
+ if (v === this.root) this.root = null;
+ // v is root, making root null
+ else {
+ if (uvBlack) {
+ // u and v both black
+ // v is leaf, fix double black at v
+ this.fixDoubleBlack(v);
+ } else {
+ // u or v is red
+ if (v.sibling()) {
+ // sibling is not null, make it red"
+ v.sibling()!.color = 0;
+ }
+ }
+ // delete v from the tree
+ if (v.isOnLeft()) parent.left = null;
+ else parent.right = null;
+ }
+ return;
+ }
+
+ if (!v.left || !v.right) {
+ // v has 1 child
+ if (v === this.root) {
+ // v is root, assign the value of u to v, and delete u
+ v.data = u.data;
+ v.left = v.right = null;
+ } else {
+ // Detach v from tree and move u up
+ if (v.isOnLeft()) parent.left = u;
+ else parent.right = u;
+ u.parent = parent;
+ if (uvBlack) this.fixDoubleBlack(u);
+ // u and v both black, fix double black at u
+ else u.color = 1; // u or v red, color u black
+ }
+ return;
+ }
+
+ // v has 2 children, swap data with successor and recurse
+ this.swapData(u, v);
+ this.deleteNode(u);
+
+ // find node that replaces a deleted node in BST
+ function BSTreplace(x: RBTreeNode): RBTreeNode | null {
+ // when node have 2 children
+ if (x.left && x.right) return successor(x.right);
+ // when leaf
+ if (!x.left && !x.right) return null;
+ // when single child
+ return x.left ?? x.right;
+ }
+ // find node that do not have a left child
+ // in the subtree of the given node
+ function successor(x: RBTreeNode): RBTreeNode {
+ let temp = x;
+ while (temp.left) temp = temp.left;
+ return temp;
+ }
+ }
+
+ fixDoubleBlack(x: RBTreeNode): void {
+ if (x === this.root) return; // Reached root
+
+ const sibling = x.sibling();
+ const parent = x.parent!;
+ if (!sibling) {
+ // No sibiling, double black pushed up
+ this.fixDoubleBlack(parent);
+ } else {
+ if (sibling.color === 0) {
+ // Sibling red
+ parent.color = 0;
+ sibling.color = 1;
+ if (sibling.isOnLeft()) this.rotateRight(parent);
+ // left case
+ else this.rotateLeft(parent); // right case
+ this.fixDoubleBlack(x);
+ } else {
+ // Sibling black
+ if (sibling.hasRedChild()) {
+ // at least 1 red children
+ if (sibling.left && sibling.left.color === 0) {
+ if (sibling.isOnLeft()) {
+ // left left
+ sibling.left.color = sibling.color;
+ sibling.color = parent.color;
+ this.rotateRight(parent);
+ } else {
+ // right left
+ sibling.left.color = parent.color;
+ this.rotateRight(sibling);
+ this.rotateLeft(parent);
+ }
+ } else {
+ if (sibling.isOnLeft()) {
+ // left right
+ sibling.right!.color = parent.color;
+ this.rotateLeft(sibling);
+ this.rotateRight(parent);
+ } else {
+ // right right
+ sibling.right!.color = sibling.color;
+ sibling.color = parent.color;
+ this.rotateLeft(parent);
+ }
+ }
+ parent.color = 1;
+ } else {
+ // 2 black children
+ sibling.color = 0;
+ if (parent.color === 1) this.fixDoubleBlack(parent);
+ else parent.color = 1;
+ }
+ }
+ }
+ }
+
+ insert(data: T): boolean {
+ // search for a position to insert
+ let parent = this.root;
+ while (parent) {
+ if (this.lt(data, parent.data)) {
+ if (!parent.left) break;
+ else parent = parent.left;
+ } else if (this.lt(parent.data, data)) {
+ if (!parent.right) break;
+ else parent = parent.right;
+ } else break;
+ }
+
+ // insert node into parent
+ const node = new RBTreeNode(data);
+ if (!parent) this.root = node;
+ else if (this.lt(node.data, parent.data)) parent.left = node;
+ else if (this.lt(parent.data, node.data)) parent.right = node;
+ else {
+ parent.count++;
+ return false;
+ }
+ node.parent = parent;
+ this.fixAfterInsert(node);
+ return true;
+ }
+
+ find(data: T): RBTreeNode | null {
+ let p = this.root;
+ while (p) {
+ if (this.lt(data, p.data)) {
+ p = p.left;
+ } else if (this.lt(p.data, data)) {
+ p = p.right;
+ } else break;
+ }
+ return p ?? null;
+ }
+
+ *inOrder(root: RBTreeNode = this.root!): Generator {
+ if (!root) return;
+ for (const v of this.inOrder(root.left!)) yield v;
+ yield root.data;
+ for (const v of this.inOrder(root.right!)) yield v;
+ }
+
+ *reverseInOrder(root: RBTreeNode = this.root!): Generator {
+ if (!root) return;
+ for (const v of this.reverseInOrder(root.right!)) yield v;
+ yield root.data;
+ for (const v of this.reverseInOrder(root.left!)) yield v;
+ }
+}
+
+class TreeSet {
+ _size: number;
+ tree: RBTree;
+ compare: Compare;
+ constructor(
+ collection: T[] | Compare = [],
+ compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0),
+ ) {
+ if (typeof collection === 'function') {
+ compare = collection;
+ collection = [];
+ }
+ this._size = 0;
+ this.compare = compare;
+ this.tree = new RBTree(compare);
+ for (const val of collection) this.add(val);
+ }
+
+ size(): number {
+ return this._size;
+ }
+
+ has(val: T): boolean {
+ return !!this.tree.find(val);
+ }
+
+ add(val: T): boolean {
+ const successful = this.tree.insert(val);
+ this._size += successful ? 1 : 0;
+ return successful;
+ }
+
+ delete(val: T): boolean {
+ const deleted = this.tree.deleteAll(val);
+ this._size -= deleted ? 1 : 0;
+ return deleted;
+ }
+
+ ceil(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(p.data, val) >= 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ floor(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(val, p.data) >= 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ higher(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(val, p.data) < 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ lower(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(p.data, val) < 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ first(): T | undefined {
+ return this.tree.inOrder().next().value;
+ }
+
+ last(): T | undefined {
+ return this.tree.reverseInOrder().next().value;
+ }
+
+ shift(): T | undefined {
+ const first = this.first();
+ if (first === undefined) return undefined;
+ this.delete(first);
+ return first;
+ }
+
+ pop(): T | undefined {
+ const last = this.last();
+ if (last === undefined) return undefined;
+ this.delete(last);
+ return last;
+ }
+
+ *[Symbol.iterator](): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *keys(): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *values(): Generator {
+ for (const val of this.tree.inOrder()) yield val;
+ return undefined;
+ }
+
+ /**
+ * Return a generator for reverse order traversing the set
+ */
+ *rvalues(): Generator {
+ for (const val of this.tree.reverseInOrder()) yield val;
+ return undefined;
+ }
+}
+
+class TreeMultiSet {
+ _size: number;
+ tree: RBTree;
+ compare: Compare;
+ constructor(
+ collection: T[] | Compare = [],
+ compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0),
+ ) {
+ if (typeof collection === 'function') {
+ compare = collection;
+ collection = [];
+ }
+ this._size = 0;
+ this.compare = compare;
+ this.tree = new RBTree(compare);
+ for (const val of collection) this.add(val);
+ }
+
+ size(): number {
+ return this._size;
+ }
+
+ has(val: T): boolean {
+ return !!this.tree.find(val);
+ }
+
+ add(val: T): boolean {
+ const successful = this.tree.insert(val);
+ this._size++;
+ return successful;
+ }
+
+ delete(val: T): boolean {
+ const successful = this.tree.delete(val);
+ if (!successful) return false;
+ this._size--;
+ return true;
+ }
+
+ count(val: T): number {
+ const node = this.tree.find(val);
+ return node ? node.count : 0;
+ }
+
+ ceil(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(p.data, val) >= 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ floor(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(val, p.data) >= 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ higher(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(val, p.data) < 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ lower(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(p.data, val) < 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ first(): T | undefined {
+ return this.tree.inOrder().next().value;
+ }
+
+ last(): T | undefined {
+ return this.tree.reverseInOrder().next().value;
+ }
+
+ shift(): T | undefined {
+ const first = this.first();
+ if (first === undefined) return undefined;
+ this.delete(first);
+ return first;
+ }
+
+ pop(): T | undefined {
+ const last = this.last();
+ if (last === undefined) return undefined;
+ this.delete(last);
+ return last;
+ }
+
+ *[Symbol.iterator](): Generator {
+ yield* this.values();
+ }
+
+ *keys(): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *values(): Generator {
+ for (const val of this.tree.inOrder()) {
+ let count = this.count(val);
+ while (count--) yield val;
+ }
+ return undefined;
+ }
+
+ /**
+ * Return a generator for reverse order traversing the multi-set
+ */
+ *rvalues(): Generator {
+ for (const val of this.tree.reverseInOrder()) {
+ let count = this.count(val);
+ while (count--) yield val;
+ }
+ return undefined;
+ }
+}
```
### **...**
diff --git a/solution/2400-2499/2454.Next Greater Element IV/README_EN.md b/solution/2400-2499/2454.Next Greater Element IV/README_EN.md
index a7d5aae768b33..5fcd54968e6be 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/README_EN.md
+++ b/solution/2400-2499/2454.Next Greater Element IV/README_EN.md
@@ -56,23 +56,34 @@ We return [-1,-1] since neither integer has any integer greater than it.
## Solutions
+**Solution 1: Sorting + Ordered Set**
+
+We can convert the elements in the array into pairs $(x, i)$, where $x$ is the value of the element and $i$ is the index of the element. Then sort by the value of the elements in descending order.
+
+Next, we traverse the sorted array, maintaining an ordered set that stores the indices of the elements. When we traverse to the element $(x, i)$, the indices of all elements greater than $x$ are already in the ordered set. We only need to find the index $j$ of the next element after $i$ in the ordered set, then the element corresponding to $j$ is the second largest element of $x$. Then, we add $i$ to the ordered set. Continue to traverse the next element.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
```python
+from sortedcontainers import SortedList
+
+
class Solution:
def secondGreaterElement(self, nums: List[int]) -> List[int]:
- stk = []
- q = []
- ans = [-1] * len(nums)
- for i, v in enumerate(nums):
- while q and q[0][0] < v:
- ans[q[0][1]] = v
- heappop(q)
- while stk and nums[stk[-1]] < v:
- heappush(q, (nums[stk[-1]], stk.pop()))
- stk.append(i)
+ arr = [(x, i) for i, x in enumerate(nums)]
+ arr.sort(key=lambda x: -x[0])
+ sl = SortedList()
+ n = len(nums)
+ ans = [-1] * n
+ for _, i in arr:
+ j = sl.bisect_right(i)
+ if j + 1 < len(sl):
+ ans[i] = nums[sl[j + 1]]
+ sl.add(i)
return ans
```
@@ -81,21 +92,22 @@ class Solution:
```java
class Solution {
public int[] secondGreaterElement(int[] nums) {
- Deque stk = new ArrayDeque<>();
- PriorityQueue q = new PriorityQueue<>((a, b) -> a[0] - b[0]);
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans, -1);
+ int[][] arr = new int[n][0];
for (int i = 0; i < n; ++i) {
- int v = nums[i];
- while (!q.isEmpty() && q.peek()[0] < v) {
- ans[q.peek()[1]] = v;
- q.poll();
- }
- while (!stk.isEmpty() && nums[stk.peek()] < v) {
- q.offer(new int[] {nums[stk.peek()], stk.pop()});
+ arr[i] = new int[] {nums[i], i};
+ }
+ Arrays.sort(arr, (a, b) -> b[0] - a[0]);
+ TreeSet ts = new TreeSet<>();
+ for (int[] pair : arr) {
+ int i = pair[1];
+ Integer j = ts.higher(i);
+ if (j != null && ts.higher(j) != null) {
+ ans[i] = nums[ts.higher(j)];
}
- stk.push(i);
+ ts.add(i);
}
return ans;
}
@@ -105,75 +117,693 @@ class Solution {
### **C++**
```cpp
-using pii = pair;
-
class Solution {
public:
vector secondGreaterElement(vector& nums) {
- stack stk;
- priority_queue, greater> q;
int n = nums.size();
vector ans(n, -1);
+ vector> arr(n);
for (int i = 0; i < n; ++i) {
- int v = nums[i];
- while (!q.empty() && q.top().first < v) {
- ans[q.top().second] = v;
- q.pop();
- }
- while (!stk.empty() && nums[stk.top()] < v) {
- q.push({nums[stk.top()], stk.top()});
- stk.pop();
+ arr[i] = {-nums[i], i};
+ }
+ sort(arr.begin(), arr.end());
+ set ts;
+ for (auto& [_, i] : arr) {
+ auto it = ts.upper_bound(i);
+ if (it != ts.end() && ts.upper_bound(*it) != ts.end()) {
+ ans[i] = nums[*ts.upper_bound(*it)];
}
- stk.push(i);
+ ts.insert(i);
}
return ans;
}
};
```
-### **Go**
-
-```go
-func secondGreaterElement(nums []int) []int {
- stk := []int{}
- q := hp{}
- n := len(nums)
- ans := make([]int, n)
- for i := range ans {
- ans[i] = -1
- }
- for i, v := range nums {
- for len(q) > 0 && q[0].v < v {
- ans[q[0].i] = v
- heap.Pop(&q)
- }
- for len(stk) > 0 && nums[stk[len(stk)-1]] < v {
- heap.Push(&q, pair{nums[stk[len(stk)-1]], stk[len(stk)-1]})
- stk = stk[:len(stk)-1]
- }
- stk = append(stk, i)
- }
- return ans
+### **TypeScript**
+
+```ts
+function secondGreaterElement(nums: number[]): number[] {
+ const n = nums.length;
+ const arr: number[][] = [];
+ for (let i = 0; i < n; ++i) {
+ arr.push([nums[i], i]);
+ }
+ arr.sort((a, b) => b[0] - a[0]);
+ const ans = Array(n).fill(-1);
+ const ts = new TreeSet();
+ for (const [_, i] of arr) {
+ let j = ts.higher(i);
+ if (j !== undefined) {
+ j = ts.higher(j);
+ if (j !== undefined) {
+ ans[i] = nums[j];
+ }
+ }
+ ts.add(i);
+ }
+ return ans;
}
-type pair struct{ v, i int }
+type Compare = (lhs: T, rhs: T) => number;
+
+class RBTreeNode {
+ data: T;
+ count: number;
+ left: RBTreeNode | null;
+ right: RBTreeNode | null;
+ parent: RBTreeNode | null;
+ color: number;
+ constructor(data: T) {
+ this.data = data;
+ this.left = this.right = this.parent = null;
+ this.color = 0;
+ this.count = 1;
+ }
+
+ sibling(): RBTreeNode | null {
+ if (!this.parent) return null; // sibling null if no parent
+ return this.isOnLeft() ? this.parent.right : this.parent.left;
+ }
-type hp []pair
+ isOnLeft(): boolean {
+ return this === this.parent!.left;
+ }
-func (h hp) Len() int { return len(h) }
-func (h hp) Less(i, j int) bool {
- a, b := h[i], h[j]
- return a.v < b.v
+ hasRedChild(): boolean {
+ return (
+ Boolean(this.left && this.left.color === 0) ||
+ Boolean(this.right && this.right.color === 0)
+ );
+ }
}
-func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
-func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
-func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
-```
-### **TypeScript**
+class RBTree {
+ root: RBTreeNode | null;
+ lt: (l: T, r: T) => boolean;
+ constructor(compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0)) {
+ this.root = null;
+ this.lt = (l: T, r: T) => compare(l, r) < 0;
+ }
-```ts
+ rotateLeft(pt: RBTreeNode): void {
+ const right = pt.right!;
+ pt.right = right.left;
+
+ if (pt.right) pt.right.parent = pt;
+ right.parent = pt.parent;
+
+ if (!pt.parent) this.root = right;
+ else if (pt === pt.parent.left) pt.parent.left = right;
+ else pt.parent.right = right;
+
+ right.left = pt;
+ pt.parent = right;
+ }
+
+ rotateRight(pt: RBTreeNode): void {
+ const left = pt.left!;
+ pt.left = left.right;
+
+ if (pt.left) pt.left.parent = pt;
+ left.parent = pt.parent;
+
+ if (!pt.parent) this.root = left;
+ else if (pt === pt.parent.left) pt.parent.left = left;
+ else pt.parent.right = left;
+
+ left.right = pt;
+ pt.parent = left;
+ }
+
+ swapColor(p1: RBTreeNode, p2: RBTreeNode): void {
+ const tmp = p1.color;
+ p1.color = p2.color;
+ p2.color = tmp;
+ }
+
+ swapData(p1: RBTreeNode, p2: RBTreeNode): void {
+ const tmp = p1.data;
+ p1.data = p2.data;
+ p2.data = tmp;
+ }
+
+ fixAfterInsert(pt: RBTreeNode): void {
+ let parent = null;
+ let grandParent = null;
+
+ while (pt !== this.root && pt.color !== 1 && pt.parent?.color === 0) {
+ parent = pt.parent;
+ grandParent = pt.parent.parent;
+
+ /* Case : A
+ Parent of pt is left child of Grand-parent of pt */
+ if (parent === grandParent?.left) {
+ const uncle = grandParent.right;
+
+ /* Case : 1
+ The uncle of pt is also red
+ Only Recoloring required */
+ if (uncle && uncle.color === 0) {
+ grandParent.color = 0;
+ parent.color = 1;
+ uncle.color = 1;
+ pt = grandParent;
+ } else {
+ /* Case : 2
+ pt is right child of its parent
+ Left-rotation required */
+ if (pt === parent.right) {
+ this.rotateLeft(parent);
+ pt = parent;
+ parent = pt.parent;
+ }
+
+ /* Case : 3
+ pt is left child of its parent
+ Right-rotation required */
+ this.rotateRight(grandParent);
+ this.swapColor(parent!, grandParent);
+ pt = parent!;
+ }
+ } else {
+ /* Case : B
+ Parent of pt is right child of Grand-parent of pt */
+ const uncle = grandParent!.left;
+
+ /* Case : 1
+ The uncle of pt is also red
+ Only Recoloring required */
+ if (uncle != null && uncle.color === 0) {
+ grandParent!.color = 0;
+ parent.color = 1;
+ uncle.color = 1;
+ pt = grandParent!;
+ } else {
+ /* Case : 2
+ pt is left child of its parent
+ Right-rotation required */
+ if (pt === parent.left) {
+ this.rotateRight(parent);
+ pt = parent;
+ parent = pt.parent;
+ }
+
+ /* Case : 3
+ pt is right child of its parent
+ Left-rotation required */
+ this.rotateLeft(grandParent!);
+ this.swapColor(parent!, grandParent!);
+ pt = parent!;
+ }
+ }
+ }
+ this.root!.color = 1;
+ }
+
+ delete(val: T): boolean {
+ const node = this.find(val);
+ if (!node) return false;
+ node.count--;
+ if (!node.count) this.deleteNode(node);
+ return true;
+ }
+
+ deleteAll(val: T): boolean {
+ const node = this.find(val);
+ if (!node) return false;
+ this.deleteNode(node);
+ return true;
+ }
+
+ deleteNode(v: RBTreeNode): void {
+ const u = BSTreplace(v);
+
+ // True when u and v are both black
+ const uvBlack = (u === null || u.color === 1) && v.color === 1;
+ const parent = v.parent!;
+
+ if (!u) {
+ // u is null therefore v is leaf
+ if (v === this.root) this.root = null;
+ // v is root, making root null
+ else {
+ if (uvBlack) {
+ // u and v both black
+ // v is leaf, fix double black at v
+ this.fixDoubleBlack(v);
+ } else {
+ // u or v is red
+ if (v.sibling()) {
+ // sibling is not null, make it red"
+ v.sibling()!.color = 0;
+ }
+ }
+ // delete v from the tree
+ if (v.isOnLeft()) parent.left = null;
+ else parent.right = null;
+ }
+ return;
+ }
+
+ if (!v.left || !v.right) {
+ // v has 1 child
+ if (v === this.root) {
+ // v is root, assign the value of u to v, and delete u
+ v.data = u.data;
+ v.left = v.right = null;
+ } else {
+ // Detach v from tree and move u up
+ if (v.isOnLeft()) parent.left = u;
+ else parent.right = u;
+ u.parent = parent;
+ if (uvBlack) this.fixDoubleBlack(u);
+ // u and v both black, fix double black at u
+ else u.color = 1; // u or v red, color u black
+ }
+ return;
+ }
+
+ // v has 2 children, swap data with successor and recurse
+ this.swapData(u, v);
+ this.deleteNode(u);
+
+ // find node that replaces a deleted node in BST
+ function BSTreplace(x: RBTreeNode): RBTreeNode | null {
+ // when node have 2 children
+ if (x.left && x.right) return successor(x.right);
+ // when leaf
+ if (!x.left && !x.right) return null;
+ // when single child
+ return x.left ?? x.right;
+ }
+ // find node that do not have a left child
+ // in the subtree of the given node
+ function successor(x: RBTreeNode): RBTreeNode {
+ let temp = x;
+ while (temp.left) temp = temp.left;
+ return temp;
+ }
+ }
+
+ fixDoubleBlack(x: RBTreeNode): void {
+ if (x === this.root) return; // Reached root
+
+ const sibling = x.sibling();
+ const parent = x.parent!;
+ if (!sibling) {
+ // No sibiling, double black pushed up
+ this.fixDoubleBlack(parent);
+ } else {
+ if (sibling.color === 0) {
+ // Sibling red
+ parent.color = 0;
+ sibling.color = 1;
+ if (sibling.isOnLeft()) this.rotateRight(parent);
+ // left case
+ else this.rotateLeft(parent); // right case
+ this.fixDoubleBlack(x);
+ } else {
+ // Sibling black
+ if (sibling.hasRedChild()) {
+ // at least 1 red children
+ if (sibling.left && sibling.left.color === 0) {
+ if (sibling.isOnLeft()) {
+ // left left
+ sibling.left.color = sibling.color;
+ sibling.color = parent.color;
+ this.rotateRight(parent);
+ } else {
+ // right left
+ sibling.left.color = parent.color;
+ this.rotateRight(sibling);
+ this.rotateLeft(parent);
+ }
+ } else {
+ if (sibling.isOnLeft()) {
+ // left right
+ sibling.right!.color = parent.color;
+ this.rotateLeft(sibling);
+ this.rotateRight(parent);
+ } else {
+ // right right
+ sibling.right!.color = sibling.color;
+ sibling.color = parent.color;
+ this.rotateLeft(parent);
+ }
+ }
+ parent.color = 1;
+ } else {
+ // 2 black children
+ sibling.color = 0;
+ if (parent.color === 1) this.fixDoubleBlack(parent);
+ else parent.color = 1;
+ }
+ }
+ }
+ }
+
+ insert(data: T): boolean {
+ // search for a position to insert
+ let parent = this.root;
+ while (parent) {
+ if (this.lt(data, parent.data)) {
+ if (!parent.left) break;
+ else parent = parent.left;
+ } else if (this.lt(parent.data, data)) {
+ if (!parent.right) break;
+ else parent = parent.right;
+ } else break;
+ }
+
+ // insert node into parent
+ const node = new RBTreeNode(data);
+ if (!parent) this.root = node;
+ else if (this.lt(node.data, parent.data)) parent.left = node;
+ else if (this.lt(parent.data, node.data)) parent.right = node;
+ else {
+ parent.count++;
+ return false;
+ }
+ node.parent = parent;
+ this.fixAfterInsert(node);
+ return true;
+ }
+
+ find(data: T): RBTreeNode | null {
+ let p = this.root;
+ while (p) {
+ if (this.lt(data, p.data)) {
+ p = p.left;
+ } else if (this.lt(p.data, data)) {
+ p = p.right;
+ } else break;
+ }
+ return p ?? null;
+ }
+
+ *inOrder(root: RBTreeNode = this.root!): Generator {
+ if (!root) return;
+ for (const v of this.inOrder(root.left!)) yield v;
+ yield root.data;
+ for (const v of this.inOrder(root.right!)) yield v;
+ }
+
+ *reverseInOrder(root: RBTreeNode = this.root!): Generator {
+ if (!root) return;
+ for (const v of this.reverseInOrder(root.right!)) yield v;
+ yield root.data;
+ for (const v of this.reverseInOrder(root.left!)) yield v;
+ }
+}
+
+class TreeSet {
+ _size: number;
+ tree: RBTree;
+ compare: Compare;
+ constructor(
+ collection: T[] | Compare = [],
+ compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0),
+ ) {
+ if (typeof collection === 'function') {
+ compare = collection;
+ collection = [];
+ }
+ this._size = 0;
+ this.compare = compare;
+ this.tree = new RBTree(compare);
+ for (const val of collection) this.add(val);
+ }
+
+ size(): number {
+ return this._size;
+ }
+
+ has(val: T): boolean {
+ return !!this.tree.find(val);
+ }
+
+ add(val: T): boolean {
+ const successful = this.tree.insert(val);
+ this._size += successful ? 1 : 0;
+ return successful;
+ }
+
+ delete(val: T): boolean {
+ const deleted = this.tree.deleteAll(val);
+ this._size -= deleted ? 1 : 0;
+ return deleted;
+ }
+
+ ceil(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(p.data, val) >= 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ floor(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(val, p.data) >= 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ higher(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(val, p.data) < 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ lower(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(p.data, val) < 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ first(): T | undefined {
+ return this.tree.inOrder().next().value;
+ }
+ last(): T | undefined {
+ return this.tree.reverseInOrder().next().value;
+ }
+
+ shift(): T | undefined {
+ const first = this.first();
+ if (first === undefined) return undefined;
+ this.delete(first);
+ return first;
+ }
+
+ pop(): T | undefined {
+ const last = this.last();
+ if (last === undefined) return undefined;
+ this.delete(last);
+ return last;
+ }
+
+ *[Symbol.iterator](): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *keys(): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *values(): Generator {
+ for (const val of this.tree.inOrder()) yield val;
+ return undefined;
+ }
+
+ /**
+ * Return a generator for reverse order traversing the set
+ */
+ *rvalues(): Generator {
+ for (const val of this.tree.reverseInOrder()) yield val;
+ return undefined;
+ }
+}
+
+class TreeMultiSet {
+ _size: number;
+ tree: RBTree;
+ compare: Compare;
+ constructor(
+ collection: T[] | Compare = [],
+ compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0),
+ ) {
+ if (typeof collection === 'function') {
+ compare = collection;
+ collection = [];
+ }
+ this._size = 0;
+ this.compare = compare;
+ this.tree = new RBTree(compare);
+ for (const val of collection) this.add(val);
+ }
+
+ size(): number {
+ return this._size;
+ }
+
+ has(val: T): boolean {
+ return !!this.tree.find(val);
+ }
+
+ add(val: T): boolean {
+ const successful = this.tree.insert(val);
+ this._size++;
+ return successful;
+ }
+
+ delete(val: T): boolean {
+ const successful = this.tree.delete(val);
+ if (!successful) return false;
+ this._size--;
+ return true;
+ }
+
+ count(val: T): number {
+ const node = this.tree.find(val);
+ return node ? node.count : 0;
+ }
+
+ ceil(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(p.data, val) >= 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ floor(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(val, p.data) >= 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ higher(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(val, p.data) < 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ lower(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(p.data, val) < 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ first(): T | undefined {
+ return this.tree.inOrder().next().value;
+ }
+
+ last(): T | undefined {
+ return this.tree.reverseInOrder().next().value;
+ }
+
+ shift(): T | undefined {
+ const first = this.first();
+ if (first === undefined) return undefined;
+ this.delete(first);
+ return first;
+ }
+
+ pop(): T | undefined {
+ const last = this.last();
+ if (last === undefined) return undefined;
+ this.delete(last);
+ return last;
+ }
+
+ *[Symbol.iterator](): Generator {
+ yield* this.values();
+ }
+
+ *keys(): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *values(): Generator {
+ for (const val of this.tree.inOrder()) {
+ let count = this.count(val);
+ while (count--) yield val;
+ }
+ return undefined;
+ }
+
+ /**
+ * Return a generator for reverse order traversing the multi-set
+ */
+ *rvalues(): Generator {
+ for (const val of this.tree.reverseInOrder()) {
+ let count = this.count(val);
+ while (count--) yield val;
+ }
+ return undefined;
+ }
+}
```
### **...**
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.cpp b/solution/2400-2499/2454.Next Greater Element IV/Solution.cpp
index 57d91102cb7fa..1f6c24bb54184 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/Solution.cpp
+++ b/solution/2400-2499/2454.Next Greater Element IV/Solution.cpp
@@ -1,24 +1,21 @@
-using pii = pair;
-
-class Solution {
-public:
- vector secondGreaterElement(vector& nums) {
- stack stk;
- priority_queue, greater> q;
- int n = nums.size();
- vector ans(n, -1);
- for (int i = 0; i < n; ++i) {
- int v = nums[i];
- while (!q.empty() && q.top().first < v) {
- ans[q.top().second] = v;
- q.pop();
- }
- while (!stk.empty() && nums[stk.top()] < v) {
- q.push({nums[stk.top()], stk.top()});
- stk.pop();
- }
- stk.push(i);
- }
- return ans;
- }
-};
\ No newline at end of file
+class Solution {
+public:
+ vector secondGreaterElement(vector& nums) {
+ int n = nums.size();
+ vector ans(n, -1);
+ vector> arr(n);
+ for (int i = 0; i < n; ++i) {
+ arr[i] = {-nums[i], i};
+ }
+ sort(arr.begin(), arr.end());
+ set ts;
+ for (auto& [_, i] : arr) {
+ auto it = ts.upper_bound(i);
+ if (it != ts.end() && ts.upper_bound(*it) != ts.end()) {
+ ans[i] = nums[*ts.upper_bound(*it)];
+ }
+ ts.insert(i);
+ }
+ return ans;
+ }
+};
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.go b/solution/2400-2499/2454.Next Greater Element IV/Solution.go
deleted file mode 100644
index dd1aeaa772cb8..0000000000000
--- a/solution/2400-2499/2454.Next Greater Element IV/Solution.go
+++ /dev/null
@@ -1,34 +0,0 @@
-func secondGreaterElement(nums []int) []int {
- stk := []int{}
- q := hp{}
- n := len(nums)
- ans := make([]int, n)
- for i := range ans {
- ans[i] = -1
- }
- for i, v := range nums {
- for len(q) > 0 && q[0].v < v {
- ans[q[0].i] = v
- heap.Pop(&q)
- }
- for len(stk) > 0 && nums[stk[len(stk)-1]] < v {
- heap.Push(&q, pair{nums[stk[len(stk)-1]], stk[len(stk)-1]})
- stk = stk[:len(stk)-1]
- }
- stk = append(stk, i)
- }
- return ans
-}
-
-type pair struct{ v, i int }
-
-type hp []pair
-
-func (h hp) Len() int { return len(h) }
-func (h hp) Less(i, j int) bool {
- a, b := h[i], h[j]
- return a.v < b.v
-}
-func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
-func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
-func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
\ No newline at end of file
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.java b/solution/2400-2499/2454.Next Greater Element IV/Solution.java
index 110c8f0165eb0..fcfa3bdb6ef18 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/Solution.java
+++ b/solution/2400-2499/2454.Next Greater Element IV/Solution.java
@@ -1,21 +1,22 @@
-class Solution {
- public int[] secondGreaterElement(int[] nums) {
- Deque stk = new ArrayDeque<>();
- PriorityQueue q = new PriorityQueue<>((a, b) -> a[0] - b[0]);
- int n = nums.length;
- int[] ans = new int[n];
- Arrays.fill(ans, -1);
- for (int i = 0; i < n; ++i) {
- int v = nums[i];
- while (!q.isEmpty() && q.peek()[0] < v) {
- ans[q.peek()[1]] = v;
- q.poll();
- }
- while (!stk.isEmpty() && nums[stk.peek()] < v) {
- q.offer(new int[] {nums[stk.peek()], stk.pop()});
- }
- stk.push(i);
- }
- return ans;
- }
+class Solution {
+ public int[] secondGreaterElement(int[] nums) {
+ int n = nums.length;
+ int[] ans = new int[n];
+ Arrays.fill(ans, -1);
+ int[][] arr = new int[n][0];
+ for (int i = 0; i < n; ++i) {
+ arr[i] = new int[] {nums[i], i};
+ }
+ Arrays.sort(arr, (a, b) -> b[0] - a[0]);
+ TreeSet ts = new TreeSet<>();
+ for (int[] pair : arr) {
+ int i = pair[1];
+ Integer j = ts.higher(i);
+ if (j != null && ts.higher(j) != null) {
+ ans[i] = nums[ts.higher(j)];
+ }
+ ts.add(i);
+ }
+ return ans;
+ }
}
\ No newline at end of file
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.py b/solution/2400-2499/2454.Next Greater Element IV/Solution.py
index 75b58be1dc698..8596b7950b61f 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/Solution.py
+++ b/solution/2400-2499/2454.Next Greater Element IV/Solution.py
@@ -1,13 +1,16 @@
-class Solution:
- def secondGreaterElement(self, nums: List[int]) -> List[int]:
- stk = []
- q = []
- ans = [-1] * len(nums)
- for i, v in enumerate(nums):
- while q and q[0][0] < v:
- ans[q[0][1]] = v
- heappop(q)
- while stk and nums[stk[-1]] < v:
- heappush(q, (nums[stk[-1]], stk.pop()))
- stk.append(i)
- return ans
+from sortedcontainers import SortedList
+
+
+class Solution:
+ def secondGreaterElement(self, nums: List[int]) -> List[int]:
+ arr = [(x, i) for i, x in enumerate(nums)]
+ arr.sort(key=lambda x: -x[0])
+ sl = SortedList()
+ n = len(nums)
+ ans = [-1] * n
+ for _, i in arr:
+ j = sl.bisect_right(i)
+ if j + 1 < len(sl):
+ ans[i] = nums[sl[j + 1]]
+ sl.add(i)
+ return ans
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.ts b/solution/2400-2499/2454.Next Greater Element IV/Solution.ts
new file mode 100644
index 0000000000000..ca95a6a4e7bcf
--- /dev/null
+++ b/solution/2400-2499/2454.Next Greater Element IV/Solution.ts
@@ -0,0 +1,661 @@
+function secondGreaterElement(nums: number[]): number[] {
+ const n = nums.length;
+ const arr: number[][] = [];
+ for (let i = 0; i < n; ++i) {
+ arr.push([nums[i], i]);
+ }
+ arr.sort((a, b) => b[0] - a[0]);
+ const ans = Array(n).fill(-1);
+ const ts = new TreeSet();
+ for (const [_, i] of arr) {
+ let j = ts.higher(i);
+ if (j !== undefined) {
+ j = ts.higher(j);
+ if (j !== undefined) {
+ ans[i] = nums[j];
+ }
+ }
+ ts.add(i);
+ }
+ return ans;
+}
+
+type Compare = (lhs: T, rhs: T) => number;
+
+class RBTreeNode {
+ data: T;
+ count: number;
+ left: RBTreeNode | null;
+ right: RBTreeNode | null;
+ parent: RBTreeNode | null;
+ color: number;
+ constructor(data: T) {
+ this.data = data;
+ this.left = this.right = this.parent = null;
+ this.color = 0;
+ this.count = 1;
+ }
+
+ sibling(): RBTreeNode | null {
+ if (!this.parent) return null; // sibling null if no parent
+ return this.isOnLeft() ? this.parent.right : this.parent.left;
+ }
+
+ isOnLeft(): boolean {
+ return this === this.parent!.left;
+ }
+
+ hasRedChild(): boolean {
+ return (
+ Boolean(this.left && this.left.color === 0) ||
+ Boolean(this.right && this.right.color === 0)
+ );
+ }
+}
+
+class RBTree {
+ root: RBTreeNode | null;
+ lt: (l: T, r: T) => boolean;
+ constructor(compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0)) {
+ this.root = null;
+ this.lt = (l: T, r: T) => compare(l, r) < 0;
+ }
+
+ rotateLeft(pt: RBTreeNode): void {
+ const right = pt.right!;
+ pt.right = right.left;
+
+ if (pt.right) pt.right.parent = pt;
+ right.parent = pt.parent;
+
+ if (!pt.parent) this.root = right;
+ else if (pt === pt.parent.left) pt.parent.left = right;
+ else pt.parent.right = right;
+
+ right.left = pt;
+ pt.parent = right;
+ }
+
+ rotateRight(pt: RBTreeNode): void {
+ const left = pt.left!;
+ pt.left = left.right;
+
+ if (pt.left) pt.left.parent = pt;
+ left.parent = pt.parent;
+
+ if (!pt.parent) this.root = left;
+ else if (pt === pt.parent.left) pt.parent.left = left;
+ else pt.parent.right = left;
+
+ left.right = pt;
+ pt.parent = left;
+ }
+
+ swapColor(p1: RBTreeNode, p2: RBTreeNode): void {
+ const tmp = p1.color;
+ p1.color = p2.color;
+ p2.color = tmp;
+ }
+
+ swapData(p1: RBTreeNode, p2: RBTreeNode): void {
+ const tmp = p1.data;
+ p1.data = p2.data;
+ p2.data = tmp;
+ }
+
+ fixAfterInsert(pt: RBTreeNode): void {
+ let parent = null;
+ let grandParent = null;
+
+ while (pt !== this.root && pt.color !== 1 && pt.parent?.color === 0) {
+ parent = pt.parent;
+ grandParent = pt.parent.parent;
+
+ /* Case : A
+ Parent of pt is left child of Grand-parent of pt */
+ if (parent === grandParent?.left) {
+ const uncle = grandParent.right;
+
+ /* Case : 1
+ The uncle of pt is also red
+ Only Recoloring required */
+ if (uncle && uncle.color === 0) {
+ grandParent.color = 0;
+ parent.color = 1;
+ uncle.color = 1;
+ pt = grandParent;
+ } else {
+ /* Case : 2
+ pt is right child of its parent
+ Left-rotation required */
+ if (pt === parent.right) {
+ this.rotateLeft(parent);
+ pt = parent;
+ parent = pt.parent;
+ }
+
+ /* Case : 3
+ pt is left child of its parent
+ Right-rotation required */
+ this.rotateRight(grandParent);
+ this.swapColor(parent!, grandParent);
+ pt = parent!;
+ }
+ } else {
+ /* Case : B
+ Parent of pt is right child of Grand-parent of pt */
+ const uncle = grandParent!.left;
+
+ /* Case : 1
+ The uncle of pt is also red
+ Only Recoloring required */
+ if (uncle != null && uncle.color === 0) {
+ grandParent!.color = 0;
+ parent.color = 1;
+ uncle.color = 1;
+ pt = grandParent!;
+ } else {
+ /* Case : 2
+ pt is left child of its parent
+ Right-rotation required */
+ if (pt === parent.left) {
+ this.rotateRight(parent);
+ pt = parent;
+ parent = pt.parent;
+ }
+
+ /* Case : 3
+ pt is right child of its parent
+ Left-rotation required */
+ this.rotateLeft(grandParent!);
+ this.swapColor(parent!, grandParent!);
+ pt = parent!;
+ }
+ }
+ }
+ this.root!.color = 1;
+ }
+
+ delete(val: T): boolean {
+ const node = this.find(val);
+ if (!node) return false;
+ node.count--;
+ if (!node.count) this.deleteNode(node);
+ return true;
+ }
+
+ deleteAll(val: T): boolean {
+ const node = this.find(val);
+ if (!node) return false;
+ this.deleteNode(node);
+ return true;
+ }
+
+ deleteNode(v: RBTreeNode): void {
+ const u = BSTreplace(v);
+
+ // True when u and v are both black
+ const uvBlack = (u === null || u.color === 1) && v.color === 1;
+ const parent = v.parent!;
+
+ if (!u) {
+ // u is null therefore v is leaf
+ if (v === this.root) this.root = null;
+ // v is root, making root null
+ else {
+ if (uvBlack) {
+ // u and v both black
+ // v is leaf, fix double black at v
+ this.fixDoubleBlack(v);
+ } else {
+ // u or v is red
+ if (v.sibling()) {
+ // sibling is not null, make it red"
+ v.sibling()!.color = 0;
+ }
+ }
+ // delete v from the tree
+ if (v.isOnLeft()) parent.left = null;
+ else parent.right = null;
+ }
+ return;
+ }
+
+ if (!v.left || !v.right) {
+ // v has 1 child
+ if (v === this.root) {
+ // v is root, assign the value of u to v, and delete u
+ v.data = u.data;
+ v.left = v.right = null;
+ } else {
+ // Detach v from tree and move u up
+ if (v.isOnLeft()) parent.left = u;
+ else parent.right = u;
+ u.parent = parent;
+ if (uvBlack) this.fixDoubleBlack(u);
+ // u and v both black, fix double black at u
+ else u.color = 1; // u or v red, color u black
+ }
+ return;
+ }
+
+ // v has 2 children, swap data with successor and recurse
+ this.swapData(u, v);
+ this.deleteNode(u);
+
+ // find node that replaces a deleted node in BST
+ function BSTreplace(x: RBTreeNode): RBTreeNode | null {
+ // when node have 2 children
+ if (x.left && x.right) return successor(x.right);
+ // when leaf
+ if (!x.left && !x.right) return null;
+ // when single child
+ return x.left ?? x.right;
+ }
+ // find node that do not have a left child
+ // in the subtree of the given node
+ function successor(x: RBTreeNode): RBTreeNode {
+ let temp = x;
+ while (temp.left) temp = temp.left;
+ return temp;
+ }
+ }
+
+ fixDoubleBlack(x: RBTreeNode): void {
+ if (x === this.root) return; // Reached root
+
+ const sibling = x.sibling();
+ const parent = x.parent!;
+ if (!sibling) {
+ // No sibiling, double black pushed up
+ this.fixDoubleBlack(parent);
+ } else {
+ if (sibling.color === 0) {
+ // Sibling red
+ parent.color = 0;
+ sibling.color = 1;
+ if (sibling.isOnLeft()) this.rotateRight(parent);
+ // left case
+ else this.rotateLeft(parent); // right case
+ this.fixDoubleBlack(x);
+ } else {
+ // Sibling black
+ if (sibling.hasRedChild()) {
+ // at least 1 red children
+ if (sibling.left && sibling.left.color === 0) {
+ if (sibling.isOnLeft()) {
+ // left left
+ sibling.left.color = sibling.color;
+ sibling.color = parent.color;
+ this.rotateRight(parent);
+ } else {
+ // right left
+ sibling.left.color = parent.color;
+ this.rotateRight(sibling);
+ this.rotateLeft(parent);
+ }
+ } else {
+ if (sibling.isOnLeft()) {
+ // left right
+ sibling.right!.color = parent.color;
+ this.rotateLeft(sibling);
+ this.rotateRight(parent);
+ } else {
+ // right right
+ sibling.right!.color = sibling.color;
+ sibling.color = parent.color;
+ this.rotateLeft(parent);
+ }
+ }
+ parent.color = 1;
+ } else {
+ // 2 black children
+ sibling.color = 0;
+ if (parent.color === 1) this.fixDoubleBlack(parent);
+ else parent.color = 1;
+ }
+ }
+ }
+ }
+
+ insert(data: T): boolean {
+ // search for a position to insert
+ let parent = this.root;
+ while (parent) {
+ if (this.lt(data, parent.data)) {
+ if (!parent.left) break;
+ else parent = parent.left;
+ } else if (this.lt(parent.data, data)) {
+ if (!parent.right) break;
+ else parent = parent.right;
+ } else break;
+ }
+
+ // insert node into parent
+ const node = new RBTreeNode(data);
+ if (!parent) this.root = node;
+ else if (this.lt(node.data, parent.data)) parent.left = node;
+ else if (this.lt(parent.data, node.data)) parent.right = node;
+ else {
+ parent.count++;
+ return false;
+ }
+ node.parent = parent;
+ this.fixAfterInsert(node);
+ return true;
+ }
+
+ find(data: T): RBTreeNode | null {
+ let p = this.root;
+ while (p) {
+ if (this.lt(data, p.data)) {
+ p = p.left;
+ } else if (this.lt(p.data, data)) {
+ p = p.right;
+ } else break;
+ }
+ return p ?? null;
+ }
+
+ *inOrder(root: RBTreeNode = this.root!): Generator {
+ if (!root) return;
+ for (const v of this.inOrder(root.left!)) yield v;
+ yield root.data;
+ for (const v of this.inOrder(root.right!)) yield v;
+ }
+
+ *reverseInOrder(root: RBTreeNode = this.root!): Generator {
+ if (!root) return;
+ for (const v of this.reverseInOrder(root.right!)) yield v;
+ yield root.data;
+ for (const v of this.reverseInOrder(root.left!)) yield v;
+ }
+}
+
+class TreeSet {
+ _size: number;
+ tree: RBTree;
+ compare: Compare;
+ constructor(
+ collection: T[] | Compare = [],
+ compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0),
+ ) {
+ if (typeof collection === 'function') {
+ compare = collection;
+ collection = [];
+ }
+ this._size = 0;
+ this.compare = compare;
+ this.tree = new RBTree(compare);
+ for (const val of collection) this.add(val);
+ }
+
+ size(): number {
+ return this._size;
+ }
+
+ has(val: T): boolean {
+ return !!this.tree.find(val);
+ }
+
+ add(val: T): boolean {
+ const successful = this.tree.insert(val);
+ this._size += successful ? 1 : 0;
+ return successful;
+ }
+
+ delete(val: T): boolean {
+ const deleted = this.tree.deleteAll(val);
+ this._size -= deleted ? 1 : 0;
+ return deleted;
+ }
+
+ ceil(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(p.data, val) >= 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ floor(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(val, p.data) >= 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ higher(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(val, p.data) < 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ lower(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(p.data, val) < 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ first(): T | undefined {
+ return this.tree.inOrder().next().value;
+ }
+
+ last(): T | undefined {
+ return this.tree.reverseInOrder().next().value;
+ }
+
+ shift(): T | undefined {
+ const first = this.first();
+ if (first === undefined) return undefined;
+ this.delete(first);
+ return first;
+ }
+
+ pop(): T | undefined {
+ const last = this.last();
+ if (last === undefined) return undefined;
+ this.delete(last);
+ return last;
+ }
+
+ *[Symbol.iterator](): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *keys(): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *values(): Generator {
+ for (const val of this.tree.inOrder()) yield val;
+ return undefined;
+ }
+
+ /**
+ * Return a generator for reverse order traversing the set
+ */
+ *rvalues(): Generator {
+ for (const val of this.tree.reverseInOrder()) yield val;
+ return undefined;
+ }
+}
+
+class TreeMultiSet {
+ _size: number;
+ tree: RBTree;
+ compare: Compare;
+ constructor(
+ collection: T[] | Compare = [],
+ compare: Compare = (l: T, r: T) => (l < r ? -1 : l > r ? 1 : 0),
+ ) {
+ if (typeof collection === 'function') {
+ compare = collection;
+ collection = [];
+ }
+ this._size = 0;
+ this.compare = compare;
+ this.tree = new RBTree(compare);
+ for (const val of collection) this.add(val);
+ }
+
+ size(): number {
+ return this._size;
+ }
+
+ has(val: T): boolean {
+ return !!this.tree.find(val);
+ }
+
+ add(val: T): boolean {
+ const successful = this.tree.insert(val);
+ this._size++;
+ return successful;
+ }
+
+ delete(val: T): boolean {
+ const successful = this.tree.delete(val);
+ if (!successful) return false;
+ this._size--;
+ return true;
+ }
+
+ count(val: T): number {
+ const node = this.tree.find(val);
+ return node ? node.count : 0;
+ }
+
+ ceil(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(p.data, val) >= 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ floor(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(val, p.data) >= 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ higher(val: T): T | undefined {
+ let p = this.tree.root;
+ let higher = null;
+ while (p) {
+ if (this.compare(val, p.data) < 0) {
+ higher = p;
+ p = p.left;
+ } else {
+ p = p.right;
+ }
+ }
+ return higher?.data;
+ }
+
+ lower(val: T): T | undefined {
+ let p = this.tree.root;
+ let lower = null;
+ while (p) {
+ if (this.compare(p.data, val) < 0) {
+ lower = p;
+ p = p.right;
+ } else {
+ p = p.left;
+ }
+ }
+ return lower?.data;
+ }
+
+ first(): T | undefined {
+ return this.tree.inOrder().next().value;
+ }
+
+ last(): T | undefined {
+ return this.tree.reverseInOrder().next().value;
+ }
+
+ shift(): T | undefined {
+ const first = this.first();
+ if (first === undefined) return undefined;
+ this.delete(first);
+ return first;
+ }
+
+ pop(): T | undefined {
+ const last = this.last();
+ if (last === undefined) return undefined;
+ this.delete(last);
+ return last;
+ }
+
+ *[Symbol.iterator](): Generator {
+ yield* this.values();
+ }
+
+ *keys(): Generator {
+ for (const val of this.values()) yield val;
+ }
+
+ *values(): Generator {
+ for (const val of this.tree.inOrder()) {
+ let count = this.count(val);
+ while (count--) yield val;
+ }
+ return undefined;
+ }
+
+ /**
+ * Return a generator for reverse order traversing the multi-set
+ */
+ *rvalues(): Generator {
+ for (const val of this.tree.reverseInOrder()) {
+ let count = this.count(val);
+ while (count--) yield val;
+ }
+ return undefined;
+ }
+}
From f9015227fbfb2d18807656e79028223fb2bccd8a Mon Sep 17 00:00:00 2001
From: Libin YANG
Date: Tue, 12 Dec 2023 10:12:42 +0800
Subject: [PATCH 3/5] feat: update solutions to lcci problems (#2088)
---
lcci/04.12.Paths with Sum/README_EN.md | 18 ++++++++++
lcci/05.01.Insert Into Bits/README_EN.md | 6 ++++
.../README_EN.md | 25 ++++++++++++-
lcci/05.03.Reverse Bits/README_EN.md | 8 +++++
lcci/05.04.Closed Number/README_EN.md | 14 ++++++++
lcci/05.06.Convert Integer/README_EN.md | 6 ++++
lcci/08.01.Three Steps Problem/README_EN.md | 36 +++++++++++++++++++
lcci/08.02.Robot in a Grid/README_EN.md | 8 +++++
lcci/08.04.Power Set/README.md | 4 +--
lcci/08.04.Power Set/README_EN.md | 16 ++++++++-
lcci/08.05.Recursive Mulitply/README_EN.md | 8 +++++
lcci/08.06.Hanota/README_EN.md | 26 ++++++++++++++
lcci/08.08.Permutation II/README_EN.md | 13 +++++++
lcci/08.09.Bracket/README_EN.md | 13 ++++++-
lcci/08.10.Color Fill/README_EN.md | 8 +++--
lcci/08.11.Coin/README_EN.md | 32 +++++++++++++++++
lcci/08.13.Pile Box/README_EN.md | 10 ++++++
lcci/10.03.Search Rotate Array/README_EN.md | 20 +++++++++++
18 files changed, 264 insertions(+), 7 deletions(-)
diff --git a/lcci/04.12.Paths with Sum/README_EN.md b/lcci/04.12.Paths with Sum/README_EN.md
index 781d9a781af82..f75af32d6e481 100644
--- a/lcci/04.12.Paths with Sum/README_EN.md
+++ b/lcci/04.12.Paths with Sum/README_EN.md
@@ -44,6 +44,24 @@ Given the following tree and sum = 22,
## Solutions
+**Solution 1: Hash Table + Prefix Sum + Recursion**
+
+We can use the idea of prefix sum to recursively traverse the binary tree, and use a hash table $cnt$ to count the occurrence of each prefix sum on the path from the root node to the current node.
+
+We design a recursive function $dfs(node, s)$, where the current node being traversed is $node$, and the prefix sum on the path from the root node to the current node is $s$. The return value of the function is the number of paths with the path sum equal to $sum$ and the path ends at the $node$ node or its subtree nodes. Therefore, the answer is $dfs(root, 0)$.
+
+The recursive process of the function $dfs(node, s)$ is as follows:
+
+- If the current node $node$ is null, return $0$.
+- Calculate the prefix sum $s$ on the path from the root node to the current node.
+- Use $cnt[s - sum]$ to represent the number of paths with the path sum equal to $sum$ and the path ends at the current node, where $cnt[s - sum]$ is the count of the prefix sum equal to $s - sum$ in $cnt$.
+- Add the count of the prefix sum $s$ by $1$, i.e., $cnt[s] = cnt[s] + 1$.
+- Recursively traverse the left and right child nodes of the current node, i.e., call the functions $dfs(node.left, s)$ and $dfs(node.right, s)$, and add their return values.
+- After the return value is calculated, subtract the count of the prefix sum $s$ of the current node by $1$, i.e., execute $cnt[s] = cnt[s] - 1$.
+- Finally, return the answer.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
+
### **Python3**
diff --git a/lcci/05.01.Insert Into Bits/README_EN.md b/lcci/05.01.Insert Into Bits/README_EN.md
index 427965844eb0f..857c3c2e0ad13 100644
--- a/lcci/05.01.Insert Into Bits/README_EN.md
+++ b/lcci/05.01.Insert Into Bits/README_EN.md
@@ -24,6 +24,12 @@
## Solutions
+**Solution 1: Bit Manipulation**
+
+First, we clear the bits from the $i$-th to the $j$-th in $N$, then we left shift $M$ by $i$ bits, and finally perform a bitwise OR operation on $M$ and $N$.
+
+The time complexity is $O(\log n)$, where $n$ is the size of $N$. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/lcci/05.02.Binary Number to String/README_EN.md b/lcci/05.02.Binary Number to String/README_EN.md
index 9911a2ec5637e..c32f00d1ca1f1 100644
--- a/lcci/05.02.Binary Number to String/README_EN.md
+++ b/lcci/05.02.Binary Number to String/README_EN.md
@@ -1,4 +1,4 @@
-# [05.02. Binary Number to String](https://leetcode.cn/problems/bianry-number-to-string-lcci)
+# [05.02. Binary Number to String](https://leetcode.cn/problems/binary-number-to-string-lcci)
[中文文档](/lcci/05.02.Binary%20Number%20to%20String/README.md)
@@ -30,6 +30,29 @@
## Solutions
+**Solution 1: Decimal Fraction to Binary Fraction**
+
+The method of converting a decimal fraction to a binary fraction is as follows: multiply the decimal part by $2$, take the integer part as the next digit of the binary fraction, and take the decimal part as the multiplicand for the next multiplication, until the decimal part is $0$ or the length of the binary fraction exceeds $32$ bits.
+
+Let's take an example, suppose we want to convert $0.8125$ to a binary fraction, the process is as follows:
+
+$$
+\begin{aligned}
+0.8125 \times 2 &= 1.625 \quad \text{take the integer part} \quad 1 \\
+0.625 \times 2 &= 1.25 \quad \text{take the integer part} \quad 1 \\
+0.25 \times 2 &= 0.5 \quad \text{take the integer part} \quad 0 \\
+0.5 \times 2 &= 1 \quad \text{take the integer part} \quad 1 \\
+\end{aligned}
+$$
+
+So the binary fraction representation of the decimal fraction $0.8125$ is $0.1101_{(2)}$.
+
+For this problem, since the real number is between $0$ and $1$, its integer part must be $0$. We only need to convert the decimal part into a binary fraction according to the above method. Stop the conversion when the decimal part is $0$ or the length of the binary fraction is not less than $32$ bits.
+
+Finally, if the decimal part is not $0$, it means that the real number cannot be represented in binary within $32$ bits, return the string `"ERROR"`. Otherwise, return the converted binary fraction.
+
+The time complexity is $O(C)$, and the space complexity is $O(C)$. Here, $C$ is the length of the binary fraction, with a maximum of $32$.
+
### **Python3**
diff --git a/lcci/05.03.Reverse Bits/README_EN.md b/lcci/05.03.Reverse Bits/README_EN.md
index 91868d77f793d..35d6af400e1a5 100644
--- a/lcci/05.03.Reverse Bits/README_EN.md
+++ b/lcci/05.03.Reverse Bits/README_EN.md
@@ -24,6 +24,14 @@
## Solutions
+**Solution 1: Two Pointers**
+
+We can use two pointers $i$ and $j$ to maintain a sliding window, where $i$ is the right pointer and $j$ is the left pointer. Each time the right pointer $i$ moves one bit to the right, if the number of $0$s in the window exceeds $1$, then the left pointer $j$ moves one bit to the right, until the number of $0$s in the window does not exceed $1$. Then calculate the length of the window at this time, compare it with the current maximum length, and take the larger value as the current maximum length.
+
+Finally, return the maximum length.
+
+The time complexity is $O(\log M)$, and the space complexity is $O(1)$. Here, $M$ is the maximum value of a 32-bit integer.
+
### **Python3**
diff --git a/lcci/05.04.Closed Number/README_EN.md b/lcci/05.04.Closed Number/README_EN.md
index e578b1c956804..199049cfb5362 100644
--- a/lcci/05.04.Closed Number/README_EN.md
+++ b/lcci/05.04.Closed Number/README_EN.md
@@ -29,6 +29,20 @@
## Solutions
+**Solution 1: Bit Manipulation**
+
+First, let's consider how to find the first number that is larger than $num$ and has the same number of $1$s in its binary representation.
+
+We can traverse the adjacent two binary bits of $num$ from low to high. If the lower bit is $1$ and the adjacent higher bit is $0$, then we have found a position where we can change the $0$ at this position to $1$ and change the $1$ at this position to $0$. Then we move all the remaining lower bits of $1$ to the lowest bit, so we get a number that is larger than $num$ and has the same number of $1$s in its binary representation.
+
+Similarly, we can find the first number that is smaller than $num$ and has the same number of $1$s in its binary representation.
+
+We can traverse the adjacent two binary bits of $num$ from low to high. If the lower bit is $0$ and the adjacent higher bit is $1$, then we have found a position where we can change the $1$ at this position to $0$ and change the $0$ at this position to $1$. Then we move all the remaining lower bits of $0$ to the lowest bit, so we get a number that is smaller than $num$ and has the same number of $1$s in its binary representation.
+
+In implementation, we can use a piece of code to handle the above two situations uniformly.
+
+The time complexity is $O(\log n)$, where $n$ is the size of $num$. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/lcci/05.06.Convert Integer/README_EN.md b/lcci/05.06.Convert Integer/README_EN.md
index d6a6814a3fb8f..e1b3f8a70d983 100644
--- a/lcci/05.06.Convert Integer/README_EN.md
+++ b/lcci/05.06.Convert Integer/README_EN.md
@@ -46,6 +46,12 @@
## Solutions
+**Solution 1: Bit Manipulation**
+
+We perform a bitwise XOR operation on A and B. The number of $1$s in the result is the number of bits that need to be changed.
+
+The time complexity is $O(\log n)$, where $n$ is the maximum value of A and B. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/lcci/08.01.Three Steps Problem/README_EN.md b/lcci/08.01.Three Steps Problem/README_EN.md
index 6f7f95261d5f3..8d26883778df9 100644
--- a/lcci/08.01.Three Steps Problem/README_EN.md
+++ b/lcci/08.01.Three Steps Problem/README_EN.md
@@ -32,6 +32,42 @@
## Solutions
+**Solution 1: Recursion**
+
+We define $f[i]$ as the number of ways to reach the $i$-th step, initially $f[1]=1$, $f[2]=2$, $f[3]=4$. The answer is $f[n]$.
+
+The recursion formula is $f[i] = f[i-1] + f[i-2] + f[i-3]$.
+
+Since $f[i]$ is only related to $f[i-1]$, $f[i-2]$, $f[i-3]$, we can use three variables $a$, $b$, $c$ to store the values of $f[i-1]$, $f[i-2]$, $f[i-3]$, reducing the space complexity to $O(1)$.
+
+The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$.
+
+**Solution 2: Matrix Quick Power to Accelerate Recursion**
+
+We set $F(n)$ to represent a $1 \times 3$ matrix $\begin{bmatrix} F_{n - 1} & F_{n - 2} & F_{n - 3} \end{bmatrix}$, where $F_{n - 1}$, $F_{n - 2}$ and $F_{n - 3}$ respectively represent the number of ways to reach the $n - 1$-th, $n - 2$-th and $n - 3$-th steps.
+
+We hope to derive $F(n)$ based on $F(n-1) = \begin{bmatrix} F_{n - 2} & F_{n - 3} & F_{n - 4} \end{bmatrix}$. That is to say, we need a matrix $base$, so that $F(n - 1) \times base = F(n)$, i.e.:
+
+$$
+\begin{bmatrix}
+F_{n - 2} & F_{n - 3} & F_{n - 4}
+\end{bmatrix} \times base = \begin{bmatrix} F_{n - 1} & F_{n - 2} & F_{n - 3} \end{bmatrix}
+$$
+
+Since $F_n = F_{n - 1} + F_{n - 2} + F_{n - 3}$, the matrix $base$ is:
+
+$$
+\begin{bmatrix}
+ 1 & 1 & 0 \\
+ 1 & 0 & 1 \\
+ 1 & 0 & 0
+\end{bmatrix}
+$$
+
+We define the initial matrix $res = \begin{bmatrix} 1 & 1 & 0 \end{bmatrix}$, then $F_n$ equals the sum of all elements in the result matrix of $res$ multiplied by $base^{n - 4}$. It can be solved using matrix quick power.
+
+The time complexity is $O(\log n)$, and the space complexity is $O(1)$.
+
### **Python3**
diff --git a/lcci/08.02.Robot in a Grid/README_EN.md b/lcci/08.02.Robot in a Grid/README_EN.md
index 784aaedf309d1..652e29c11defe 100644
--- a/lcci/08.02.Robot in a Grid/README_EN.md
+++ b/lcci/08.02.Robot in a Grid/README_EN.md
@@ -32,6 +32,14 @@
## Solutions
+**Solution 1: DFS (Depth-First Search)**
+
+We can use depth-first search to solve this problem. We start from the top left corner and move right or down until we reach the bottom right corner. If at some step, we find that the current position is an obstacle, or the current position is already in the path, then we return. Otherwise, we add the current position to the path and mark the current position as visited, then continue to move right or down.
+
+If we can finally reach the bottom right corner, then we have found a feasible path, otherwise, it means there is no feasible path.
+
+The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the grid, respectively.
+
### **Python3**
diff --git a/lcci/08.04.Power Set/README.md b/lcci/08.04.Power Set/README.md
index ee64bd0d193c7..62052a908c4f6 100644
--- a/lcci/08.04.Power Set/README.md
+++ b/lcci/08.04.Power Set/README.md
@@ -35,7 +35,7 @@
当前枚举到的元素下标为 $u$,我们可以选择将其加入子集 $t$ 中,也可以选择不加入子集 $t$ 中。递归这两种选择,即可得到所有的子集。
-时间复杂度 $O(n\times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。数组中每个元素有两种状态,即选择或不选择,共 $2^n$ 种状态,每种状态需要 $O(n)$ 的时间来构造子集。
+时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。数组中每个元素有两种状态,即选择或不选择,共 $2^n$ 种状态,每种状态需要 $O(n)$ 的时间来构造子集。
**方法二:二进制枚举**
@@ -43,7 +43,7 @@
我们可以使用 $2^n$ 个二进制数来表示 $n$ 个元素的所有子集,若某个二进制数 `mask` 的第 $i$ 位为 $1$,表示子集中包含数组第 $i$ 个元素 $v$;若为 $0$,表示子集中不包含数组第 $i$ 个元素 $v$。
-时间复杂度 $O(n\times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。一共有 $2^n$ 个子集,每个子集需要 $O(n)$ 的时间来构造。
+时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。一共有 $2^n$ 个子集,每个子集需要 $O(n)$ 的时间来构造。
diff --git a/lcci/08.04.Power Set/README_EN.md b/lcci/08.04.Power Set/README_EN.md
index 102966b9a690a..03dbdf4f8ad85 100644
--- a/lcci/08.04.Power Set/README_EN.md
+++ b/lcci/08.04.Power Set/README_EN.md
@@ -40,7 +40,21 @@
## Solutions
-Backtracking
+**Solution 1: Recursive Enumeration**
+
+We design a recursive function $dfs(u, t)$, where $u$ is the index of the current element being enumerated, and $t$ is the current subset.
+
+For the current element with index $u$, we can choose to add it to the subset $t$, or we can choose not to add it to the subset $t$. Recursively making these two choices will yield all subsets.
+
+The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. Each element in the array has two states, namely chosen or not chosen, for a total of $2^n$ states. Each state requires $O(n)$ time to construct the subset.
+
+**Solution 2: Binary Enumeration**
+
+We can rewrite the recursive process in Method 1 into an iterative form, that is, using binary enumeration to enumerate all subsets.
+
+We can use $2^n$ binary numbers to represent all subsets of $n$ elements. If the $i$-th bit of a binary number `mask` is $1$, it means that the subset contains the $i$-th element $v$ of the array; if it is $0$, it means that the subset does not contain the $i$-th element $v$ of the array.
+
+The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. There are a total of $2^n$ subsets, and each subset requires $O(n)$ time to construct.
diff --git a/lcci/08.05.Recursive Mulitply/README_EN.md b/lcci/08.05.Recursive Mulitply/README_EN.md
index 4dcbc044f9423..9e8a17c683282 100644
--- a/lcci/08.05.Recursive Mulitply/README_EN.md
+++ b/lcci/08.05.Recursive Mulitply/README_EN.md
@@ -28,6 +28,14 @@
## Solutions
+**Solution 1: Recursion + Bit Manipulation**
+
+First, we check if $B$ is $1$. If it is, we directly return $A$.
+
+Otherwise, we check if $B$ is an odd number. If it is, we can right shift $B$ by one bit, then recursively call the function, and finally left shift the result by one bit and add $A$. If not, we can right shift $B$ by one bit, then recursively call the function, and finally left shift the result by one bit.
+
+The time complexity is $O(\log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the size of $B$.
+
### **Python3**
diff --git a/lcci/08.06.Hanota/README_EN.md b/lcci/08.06.Hanota/README_EN.md
index 2f79c257124f9..68e2482b327db 100644
--- a/lcci/08.06.Hanota/README_EN.md
+++ b/lcci/08.06.Hanota/README_EN.md
@@ -32,6 +32,32 @@
## Solutions
+**Solution 1: Recursion**
+
+We design a function $dfs(n, a, b, c)$, which represents moving $n$ disks from $a$ to $c$, with $b$ as the auxiliary rod.
+
+First, we move $n - 1$ disks from $a$ to $b$, then move the $n$-th disk from $a$ to $c$, and finally move $n - 1$ disks from $b$ to $c$.
+
+The time complexity is $O(2^n)$, and the space complexity is $O(n)$. Here, $n$ is the number of disks.
+
+**Solution 2: Iteration (Stack)**
+
+We can use a stack to simulate the recursive process.
+
+We define a struct $Task$, which represents a task, where $n$ represents the number of disks, and $a$, $b$, $c$ represent the three rods.
+
+We push the initial task $Task(len(A), A, B, C)$ into the stack, and then continuously process the task at the top of the stack until the stack is empty.
+
+If $n = 1$, then we directly move the disk from $a$ to $c$.
+
+Otherwise, we push three subtasks into the stack, which are:
+
+1. Move $n - 1$ disks from $b$ to $c$ with the help of $a$;
+2. Move the $n$-th disk from $a$ to $c$;
+3. Move $n - 1$ disks from $a$ to $b$ with the help of $c$.
+
+The time complexity is $O(2^n)$, and the space complexity is $O(n)$. Here, $n$ is the number of disks.
+
### **Python3**
diff --git a/lcci/08.08.Permutation II/README_EN.md b/lcci/08.08.Permutation II/README_EN.md
index b1bdcae45f228..1c32e194558ce 100644
--- a/lcci/08.08.Permutation II/README_EN.md
+++ b/lcci/08.08.Permutation II/README_EN.md
@@ -29,6 +29,19 @@
## Solutions
+**Solution 1: Sorting + Backtracking**
+
+We can first sort the string by characters, which allows us to put duplicate characters together and makes it easier for us to remove duplicates.
+
+Then, we design a function $dfs(i)$, which means that we need to fill in the character at the $i$-th position. The specific implementation of the function is as follows:
+
+- If $i = n$, it means that we have finished filling in, add the current permutation to the answer array, and then return.
+- Otherwise, we enumerate the character $s[j]$ at the $i$-th position, where the range of $j$ is $[0, n - 1]$. We need to ensure that $s[j]$ has not been used and is different from the previously enumerated characters, so as to ensure that the current permutation is not repeated. If the conditions are met, we can fill in $s[j]$, and continue to recursively fill in the next position, that is, call $dfs(i + 1)$. After the recursive call ends, we need to mark $s[j]$ as unused for later enumeration.
+
+In the main function, we first sort the string, then call $dfs(0)$, that is, start filling from the $0$-th position, and finally return the answer array.
+
+The time complexity is $O(n \times n!)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$. $n!$ enumerations need to be performed, and each enumeration requires $O(n)$ time to determine whether it is repeated. In addition, we need a marker array to mark whether each position has been used, so the space complexity is $O(n)$.
+
### **Python3**
diff --git a/lcci/08.09.Bracket/README_EN.md b/lcci/08.09.Bracket/README_EN.md
index 1348c37920b33..cc2b905c877e9 100644
--- a/lcci/08.09.Bracket/README_EN.md
+++ b/lcci/08.09.Bracket/README_EN.md
@@ -30,7 +30,18 @@
## Solutions
-DFS.
+**Solution 1: DFS + Pruning**
+
+The range of $n$ in the problem is $[1, 8]$, so we can directly solve this problem quickly through "brute force search + pruning".
+
+We design a function `dfs(l, r, t)`, where $l$ and $r$ represent the number of left and right parentheses respectively, and $t$ represents the current parentheses sequence. Then we can get the following recursive structure:
+
+- If $l > n$ or $r > n$ or $l < r$, then the current parentheses combination $t$ is illegal, return directly;
+- If $l = n$ and $r = n$, then the current parentheses combination $t$ is legal, add it to the answer array `ans`, and return directly;
+- We can choose to add a left parenthesis, and recursively execute `dfs(l + 1, r, t + "(")`;
+- We can also choose to add a right parenthesis, and recursively execute `dfs(l, r + 1, t + ")")`.
+
+The time complexity is $O(2^{n\times 2} \times n)$, and the space complexity is $O(n)$.
diff --git a/lcci/08.10.Color Fill/README_EN.md b/lcci/08.10.Color Fill/README_EN.md
index cbd96bc76234c..2b764190e6c0a 100644
--- a/lcci/08.10.Color Fill/README_EN.md
+++ b/lcci/08.10.Color Fill/README_EN.md
@@ -38,9 +38,13 @@ to the starting pixel.
## Solutions
-DFS or BFS.
+**Solution 1: Flood Fill Algorithm**
-> Flood fill, also called seed fill, is a flooding algorithm that determines and alters the area connected to a given node in a multi-dimensional array with some matching attribute. It is used in the "bucket" fill tool of paint programs to fill connected, similarly-colored areas with a different color.
+The Flood Fill algorithm is a classic algorithm used to extract several connected points from a region and distinguish them from other adjacent regions (or color them differently). It is named for its strategy, which is similar to a flood spreading from one area to all reachable areas.
+
+The simplest implementation method is to use the recursive method of DFS, or it can be implemented iteratively using BFS.
+
+The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the image, respectively.
diff --git a/lcci/08.11.Coin/README_EN.md b/lcci/08.11.Coin/README_EN.md
index 69b03b5e17882..a6e5e9f4482c0 100644
--- a/lcci/08.11.Coin/README_EN.md
+++ b/lcci/08.11.Coin/README_EN.md
@@ -45,6 +45,38 @@
## Solutions
+**Solution 1: Dynamic Programming**
+
+We define $f[i][j]$ as the number of ways to make up the total amount $j$ using only the first $i$ types of coins. Initially, $f[0][0]=1$, and the rest of the elements are $0$. The answer is $f[4][n]$.
+
+Considering $f[i][j]$, we can enumerate the number of the $i$-th type of coin used, $k$, where $0 \leq k \leq j / c_i$, then $f[i][j]$ is equal to the sum of all $f[i−1][j−k \times c_i]$. Since the number of coins is infinite, $k$ can start from $0$. That is, the state transition equation is as follows:
+
+$$
+f[i][j] = f[i - 1][j] + f[i - 1][j - c_i] + \cdots + f[i - 1][j - k \times c_i]
+$$
+
+Let $j = j - c_i$, then the above state transition equation can be written as:
+
+$$
+f[i][j - c_i] = f[i - 1][j - c_i] + f[i - 1][j - 2 \times c_i] + \cdots + f[i - 1][j - k \times c_i]
+$$
+
+Substitute the second equation into the first equation to get:
+
+$$
+f[i][j]=
+\begin{cases}
+f[i - 1][j] + f[i][j - c_i], & j \geq c_i \\
+f[i - 1][j], & j < c_i
+\end{cases}
+$$
+
+The final answer is $f[4][n]$.
+
+The time complexity is $O(C \times n)$, and the space complexity is $O(C \times n)$, where $C$ is the number of types of coins.
+
+We notice that the calculation of $f[i][j]$ is only related to $f[i−1][..]$, so we can remove the first dimension and optimize the space complexity to $O(n)$.
+
### **Python3**
diff --git a/lcci/08.13.Pile Box/README_EN.md b/lcci/08.13.Pile Box/README_EN.md
index d1ce53422e55f..4e69a2b85fd75 100644
--- a/lcci/08.13.Pile Box/README_EN.md
+++ b/lcci/08.13.Pile Box/README_EN.md
@@ -29,6 +29,16 @@
## Solutions
+**Solution 1: Sorting + Dynamic Programming**
+
+First, we sort the boxes in ascending order by width and descending order by depth, then use dynamic programming to solve the problem.
+
+We define $f[i]$ as the maximum height with the $i$-th box at the bottom. For $f[i]$, we enumerate $j \in [0, i)$, if $box[j][1] < box[i][1]$ and $box[j][2] < box[i][2]$, then we can put the $j$-th box on top of the $i$-th box, in which case $f[i] = \max\{f[i], f[j]\}$. Finally, we add the height of the $i$-th box to $f[i]$ to get the final value of $f[i]$.
+
+The answer is the maximum value in $f$.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the number of boxes.
+
### **Python3**
diff --git a/lcci/10.03.Search Rotate Array/README_EN.md b/lcci/10.03.Search Rotate Array/README_EN.md
index f63f2cd018ee7..e295f94c36cf8 100644
--- a/lcci/10.03.Search Rotate Array/README_EN.md
+++ b/lcci/10.03.Search Rotate Array/README_EN.md
@@ -28,6 +28,26 @@
## Solutions
+**Solution 1: Binary Search**
+
+We define the left boundary of the binary search as $l=0$ and the right boundary as $r=n-1$, where $n$ is the length of the array.
+
+In each binary search process, we get the current midpoint $mid=(l+r)/2$.
+
+- If $nums[mid] > nums[r]$, it means that $[l,mid]$ is ordered. If $nums[l] \leq target \leq nums[mid]$, it means that $target$ is in $[l,mid]$, otherwise $target$ is in $[mid+1,r]$.
+- If $nums[mid] < nums[r]$, it means that $[mid+1,r]$ is ordered. If $nums[mid] < target \leq nums[r]$, it means that $target$ is in $[mid+1,r]$, otherwise $target$ is in $[l,mid]$.
+- If $nums[mid] = nums[r]$, it means that the elements $nums[mid]$ and $nums[r]$ are equal. At this time, we cannot determine which interval $target$ is in, we can only decrease $r$ by $1$.
+
+After the binary search ends, if $nums[l] = target$, it means that the target value $target$ exists in the array, otherwise it does not exist.
+
+Note that if initially $nums[l] = nums[r]$, we loop to decrease $r$ by $1$ until $nums[l] \neq nums[r]$.
+
+The time complexity is approximately $O(\log n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array.
+
+Similar problems:
+
+- [81. Search in Rotated Sorted Array II](/solution/0000-0099/0081.Search%20in%20Rotated%20Sorted%20Array%20II/README.md)
+
### **Python3**
From 6a6cc3f4c3ed2329cef9a020a542a65d5268ce03 Mon Sep 17 00:00:00 2001
From: Libin YANG
Date: Tue, 12 Dec 2023 15:48:26 +0800
Subject: [PATCH 4/5] feat: add solutions to lc problems (#2089)
---
.../README_EN.md | 6 +
.../README_EN.md | 16 +++
.../README.md | 8 +-
.../README_EN.md | 14 +++
.../README.md | 4 +-
.../README_EN.md | 6 +
.../README_EN.md | 8 ++
.../README.md | 2 +-
.../README_EN.md | 18 +++
.../README_EN.md | 17 +++
.../2401.Longest Nice Subarray/README_EN.md | 16 +++
.../2402.Meeting Rooms III/README.md | 8 +-
.../2402.Meeting Rooms III/README_EN.md | 16 +++
.../README.md | 8 +-
.../README_EN.md | 8 ++
.../README_EN.md | 6 +
.../README.md | 2 +-
.../README_EN.md | 8 ++
.../README.md | 6 +-
.../README_EN.md | 11 ++
.../README.md | 6 +-
.../README_EN.md | 19 +++
.../2400-2499/2408.Design SQL/README_EN.md | 6 +
.../README_EN.md | 6 +
.../README.md | 2 +-
.../README_EN.md | 6 +
.../README.md | 4 +-
.../README_EN.md | 10 ++
.../README.md | 4 +-
.../README_EN.md | 6 +
.../2413.Smallest Even Multiple/README.md | 2 +-
.../2413.Smallest Even Multiple/README_EN.md | 6 +
.../README.md | 2 +-
.../README_EN.md | 6 +
.../README.md | 2 +-
.../README_EN.md | 8 ++
.../2418.Sort the People/README_EN.md | 8 ++
.../README_EN.md | 10 ++
.../2420.Find All Good Indices/README.md | 4 +-
.../2420.Find All Good Indices/README_EN.md | 10 ++
.../2421.Number of Good Paths/README.md | 2 +-
.../2421.Number of Good Paths/README_EN.md | 8 ++
.../README.md | 4 +-
.../README_EN.md | 16 ++-
.../README_EN.md | 10 ++
.../2424.Longest Uploaded Prefix/README_EN.md | 8 ++
.../README.md | 2 +-
.../README_EN.md | 12 ++
.../README.md | 6 +-
.../README_EN.md | 8 ++
.../README_EN.md | 12 ++
.../README.md | 2 +-
.../README_EN.md | 6 +
.../2400-2499/2429.Minimize XOR/README_EN.md | 6 +
.../README_EN.md | 23 ++++
.../README.md | 2 +-
.../README_EN.md | 14 +++
.../README.md | 2 +-
.../README_EN.md | 10 ++
.../README.md | 2 +-
.../README_EN.md | 24 ++++
.../README_EN.md | 12 ++
.../README.md | 4 +-
.../README_EN.md | 30 +++++
.../README.md | 2 +-
.../README_EN.md | 10 ++
.../README_EN.md | 14 +++
.../README.md | 2 +-
.../README_EN.md | 6 +
.../2439.Minimize Maximum of Array/README.md | 2 +-
.../README_EN.md | 6 +
.../README.md | 6 +-
.../README_EN.md | 12 ++
.../README_EN.md | 10 ++
.../README_EN.md | 6 +
.../README.md | 2 +-
.../README_EN.md | 6 +
.../README.md | 4 +-
.../README_EN.md | 14 +++
.../README.md | 2 +-
.../README_EN.md | 8 ++
.../README_EN.md | 8 ++
.../README.md | 4 +-
.../README_EN.md | 8 ++
.../README_EN.md | 32 ++++++
.../README.md | 4 +-
.../README_EN.md | 12 ++
.../README_EN.md | 6 +
.../2451.Odd String Difference/README_EN.md | 6 +
.../2453.Destroy Sequential Targets/README.md | 4 +-
.../README_EN.md | 6 +
.../2454.Next Greater Element IV/README.md | 4 +-
.../2454.Next Greater Element IV/README_EN.md | 4 +-
.../Solution.java | 2 +-
.../2454.Next Greater Element IV/Solution.ts | 2 +-
.../README_EN.md | 6 +
.../README_EN.md | 8 ++
.../README_EN.md | 21 ++++
.../README_EN.md | 24 ++++
.../README_EN.md | 10 ++
.../README_EN.md | 12 ++
.../README_EN.md | 6 +
.../README_EN.md | 12 ++
.../README_EN.md | 8 ++
.../README.md | 2 +-
.../README_EN.md | 6 +
.../README_EN.md | 6 +
.../README_EN.md | 13 +++
.../README_EN.md | 14 +++
.../README_EN.md | 14 +++
.../2469.Convert the Temperature/README_EN.md | 6 +
.../README_EN.md | 6 +
.../README.md | 2 +-
.../README_EN.md | 6 +
.../README_EN.md | 17 +++
.../README_EN.md | 6 +
.../README.md | 106 +++++++++++++++++
.../README_EN.md | 108 +++++++++++++++++-
.../Solution.cpp | 12 +-
.../Solution.go | 12 +-
.../Solution.java | 12 +-
.../Solution.py | 2 +-
.../Solution.rs | 13 +++
.../Solution.ts | 10 +-
solution/config.py | 1 +
125 files changed, 1150 insertions(+), 85 deletions(-)
create mode 100644 solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.rs
diff --git a/solution/2300-2399/2300.Successful Pairs of Spells and Potions/README_EN.md b/solution/2300-2399/2300.Successful Pairs of Spells and Potions/README_EN.md
index a6dd10e42fd27..5497820c1443b 100644
--- a/solution/2300-2399/2300.Successful Pairs of Spells and Potions/README_EN.md
+++ b/solution/2300-2399/2300.Successful Pairs of Spells and Potions/README_EN.md
@@ -48,6 +48,12 @@ Thus, [2,0,2] is returned.
## Solutions
+**Solution 1: Sorting + Binary Search**
+
+We can sort the potion array, then traverse the spell array. For each spell $v$, we use binary search to find the first potion that is greater than or equal to $\frac{success}{v}$. We mark its index as $i$. The length of the potion array minus $i$ is the number of potions that can successfully combine with this spell.
+
+The time complexity is $O((m + n) \times \log m)$, and the space complexity is $O(\log n)$. Here, $m$ and $n$ are the lengths of the potion array and the spell array, respectively.
+
### **Python3**
diff --git a/solution/2300-2399/2301.Match Substring After Replacement/README_EN.md b/solution/2300-2399/2301.Match Substring After Replacement/README_EN.md
index 43e16fed518b6..b8fc469dbe92d 100644
--- a/solution/2300-2399/2301.Match Substring After Replacement/README_EN.md
+++ b/solution/2300-2399/2301.Match Substring After Replacement/README_EN.md
@@ -58,6 +58,22 @@ Now sub = "l33tb" is a substring of s, so we return true.
## Solutions
+**Solution 1: Hash Table + Enumeration**
+
+First, we use a hash table $d$ to record the set of characters that each character can be replaced with.
+
+Then we enumerate all substrings of length $sub$ in $s$, and judge whether the string $sub$ can be obtained by replacement. If it can, return `true`, otherwise enumerate the next substring.
+
+At the end of the enumeration, it means that $sub$ cannot be obtained by replacing any substring in $s$, so return `false`.
+
+The time complexity is $O(m \times n)$, and the space complexity is $O(C^2)$. Here, $m$ and $n$ are the lengths of the strings $s$ and $sub$ respectively, and $C$ is the size of the character set.
+
+**Solution 2: Array + Enumeration**
+
+Since the character set only contains uppercase and lowercase English letters and numbers, we can directly use a $128 \times 128$ array $d$ to record the set of characters that each character can be replaced with.
+
+The time complexity is $O(m \times n)$, and the space complexity is $O(C^2)$.
+
### **Python3**
diff --git a/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README.md b/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README.md
index 4334f5286bb67..edd42477ad0fe 100644
--- a/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README.md
+++ b/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README.md
@@ -60,17 +60,17 @@
**方法一:前缀和 + 二分查找**
-我们先计算出数组 `nums` 的前缀和数组 $s$,其中 $s[i]$ 表示数组 `nums` 前 $i$ 个元素的和。
+我们先计算出数组 $nums$ 的前缀和数组 $s$,其中 $s[i]$ 表示数组 $nums$ 前 $i$ 个元素的和。
-接下来,我们枚举数组 `nums` 每个元素作为子数组的最后一个元素,对于每个元素,我们可以通过二分查找的方式找到最大的长度 $l$,使得 $s[i] - s[i - l] \times l < k$。那么以该元素为最后一个元素的子数组个数即为 $l$,我们将所有的 $l$ 相加即为答案。
+接下来,我们枚举数组 $nums$ 每个元素作为子数组的最后一个元素,对于每个元素,我们可以通过二分查找的方式找到最大的长度 $l$,使得 $s[i] - s[i - l] \times l < k$。那么以该元素为最后一个元素的子数组个数即为 $l$,我们将所有的 $l$ 相加即为答案。
-时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
**方法二:双指针**
我们可以使用双指针的方式,维护一个滑动窗口,使得窗口内的元素和小于 $k$。那么以当前元素为最后一个元素的子数组个数即为窗口的长度,我们将所有的窗口长度相加即为答案。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `nums` 的长度。
+时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$。
diff --git a/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README_EN.md b/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README_EN.md
index a372572d952f6..c50fe397433eb 100644
--- a/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README_EN.md
+++ b/solution/2300-2399/2302.Count Subarrays With Score Less Than K/README_EN.md
@@ -52,6 +52,20 @@ Thus, there are 5 subarrays having scores less than 5.
## Solutions
+**Solution 1: Prefix Sum + Binary Search**
+
+First, we calculate the prefix sum array $s$ of the array $nums$, where $s[i]$ represents the sum of the first $i$ elements of the array $nums$.
+
+Next, we enumerate each element of the array $nums$ as the last element of the subarray. For each element, we can find the maximum length $l$ such that $s[i] - s[i - l] \times l < k$ by binary search. The number of subarrays with this element as the last element is $l$, and we add all $l$ to get the answer.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
+
+**Solution 2: Two Pointers**
+
+We can use two pointers to maintain a sliding window, so that the sum of the elements in the window is less than $k$. The number of subarrays with the current element as the last element is the length of the window, and we add all window lengths to get the answer.
+
+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/2300-2399/2303.Calculate Amount Paid in Taxes/README.md b/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README.md
index 61a93475a71f2..17697b88cce17 100644
--- a/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README.md
+++ b/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README.md
@@ -70,9 +70,9 @@
**方法一:模拟**
-遍历 `brackets`,对于每个税级,计算该税级的税额,然后累加即可。
+我们遍历 `brackets`,对于每个税级,计算该税级的税额,然后累加即可。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为 `brackets` 的长度。
+时间复杂度 $O(n)$,其中 $n$ 为 `brackets` 的长度。空间复杂度 $O(1)$。
diff --git a/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README_EN.md b/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README_EN.md
index df8315a508ccd..3d9c9d3d6ef31 100644
--- a/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README_EN.md
+++ b/solution/2300-2399/2303.Calculate Amount Paid in Taxes/README_EN.md
@@ -64,6 +64,12 @@ You have no income to tax, so you have to pay a total of 0 in taxes.
## Solutions
+**Solution 1: Simulation**
+
+We traverse `brackets`, and for each tax bracket, we calculate the tax amount for that bracket, then accumulate it.
+
+The time complexity is $O(n)$, where $n$ is the length of `brackets`. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2300-2399/2305.Fair Distribution of Cookies/README_EN.md b/solution/2300-2399/2305.Fair Distribution of Cookies/README_EN.md
index e15629afe2ffd..5cdbfaf9834ba 100644
--- a/solution/2300-2399/2305.Fair Distribution of Cookies/README_EN.md
+++ b/solution/2300-2399/2305.Fair Distribution of Cookies/README_EN.md
@@ -47,6 +47,14 @@ It can be shown that there is no distribution with an unfairness less than 7.
## Solutions
+**Solution 1: Backtracking + Pruning**
+
+First, we sort the array $cookies$ in descending order (to reduce the number of searches), and then create an array $cnt$ of length $k$ to store the number of cookies each child gets. Also, we use a variable $ans$ to maintain the current minimum degree of unfairness, initialized to a very large value.
+
+Next, we start from the first snack pack. For the current snack pack $i$, we enumerate each child $j$. If the cookies $cookies[i]$ in the current snack pack are given to child $j$, making the degree of unfairness greater than or equal to $ans$, or the number of cookies the current child already has is the same as the previous child, then we don't need to consider giving the cookies in the current snack pack to child $j$, just skip it (pruning). Otherwise, we give the cookies $cookies[i]$ in the current snack pack to child $j$, and then continue to consider the next snack pack. When we have considered all the snack packs, we update the value of $ans$, then backtrack to the previous snack pack, and continue to enumerate which child to give the cookies in the current snack pack to.
+
+Finally, we return $ans$.
+
### **Python3**
diff --git a/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README.md b/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README.md
index bb9e6922920d8..7881e95490b5d 100644
--- a/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README.md
+++ b/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README.md
@@ -70,7 +70,7 @@
接下来我们只要获取 $mask$ 的二进制表示中最高位的 $1$ 的位置,将其转换为对应的大写字母即可。如果所有二进制位都不为 $1$,说明不存在大小写同时出现的字母,返回空字符串。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 是字符串 $s$ 的长度。
+时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(1)$。
diff --git a/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README_EN.md b/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README_EN.md
index 341206113e8b1..de9f263bcc6b2 100644
--- a/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README_EN.md
+++ b/solution/2300-2399/2309.Greatest English Letter in Upper and Lower Case/README_EN.md
@@ -47,6 +47,24 @@ There is no letter that appears in both lower and upper case.
## Solutions
+**Solution 1: Hash Table + Enumeration**
+
+First, we use a hash table $ss$ to record all the letters that appear in the string $s$. Then we start enumerating from the last letter of the uppercase alphabet. If both the uppercase and lowercase forms of the current letter are in $ss$, we return that letter.
+
+At the end of the enumeration, if no letter that meets the conditions is found, we return an empty string.
+
+The time complexity is $O(n)$, and the space complexity is $O(C)$. Here, $n$ and $C$ are the length of the string $s$ and the size of the character set, respectively.
+
+**Solution 2: Bit Manipulation (Space Optimization)**
+
+We can use two integers $mask1$ and $mask2$ to record the lowercase and uppercase letters that appear in the string $s$, respectively. The $i$-th bit of $mask1$ indicates whether the $i$-th lowercase letter appears, and the $i$-th bit of $mask2$ indicates whether the $i$-th uppercase letter appears.
+
+Then we perform a bitwise AND operation on $mask1$ and $mask2$. The $i$-th bit of the resulting $mask$ indicates whether the $i$-th letter appears in both uppercase and lowercase.
+
+Next, we just need to get the position of the highest $1$ in the binary representation of $mask$, and convert it to the corresponding uppercase letter. If all binary bits are not $1$, it means that there is no letter that appears in both uppercase and lowercase, so we return an empty string.
+
+The time complexity is $O(n)$, where $n$ is the length of the string $s$. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2400.Number of Ways to Reach a Position After Exactly k Steps/README_EN.md b/solution/2400-2499/2400.Number of Ways to Reach a Position After Exactly k Steps/README_EN.md
index 43fc93c3ebfd1..d3ddfcf70bd29 100644
--- a/solution/2400-2499/2400.Number of Ways to Reach a Position After Exactly k Steps/README_EN.md
+++ b/solution/2400-2499/2400.Number of Ways to Reach a Position After Exactly k Steps/README_EN.md
@@ -41,6 +41,23 @@ It can be proven that no other way is possible, so we return 3.
## Solutions
+**Solution 1: Memorization Search**
+
+We design a function $dfs(i, j)$, which represents the number of ways to reach the target position when the current position is $i$ distance from the target position and there are $j$ steps left. The answer is $dfs(abs(startPos - endPos), k)$.
+
+The calculation method of the function $dfs(i, j)$ is as follows:
+
+- If $i \gt j$ or $j \lt 0$, it means that the current distance from the target position is greater than the remaining steps, or the remaining steps are negative. In this case, it is impossible to reach the target position, so return $0$;
+- If $j = 0$, it means that there are no steps left. At this time, only when the current distance from the target position is $0$ can the target position be reached, otherwise it is impossible to reach the target position. Return $1$ or $0$;
+- Otherwise, the current distance from the target position is $i$, and there are $j$ steps left. There are two ways to reach the target position:
+ - Move one step to the left, the current distance from the target position is $i + 1$, and there are $j - 1$ steps left. The number of methods is $dfs(i + 1, j - 1)$;
+ - Move one step to the right, the current distance from the target position is $abs(i - 1)$, and there are $j - 1$ steps left. The number of methods is $dfs(abs(i - 1), j - 1)$;
+- Finally, return the result of the sum of the two methods modulo $10^9 + 7$.
+
+To avoid repeated calculations, we use memorization search, that is, we use a two-dimensional array $f$ to record the result of the function $dfs(i, j)$. When the function $dfs(i, j)$ is called, if $f[i][j]$ is not $-1$, return $f[i][j]$ directly, otherwise calculate the value of $f[i][j]$, and return $f[i][j]$.
+
+The time complexity is $O(k^2)$, and the space complexity is $O(k^2)$. Here, $k$ is the number of steps given in the problem.
+
### **Python3**
diff --git a/solution/2400-2499/2401.Longest Nice Subarray/README_EN.md b/solution/2400-2499/2401.Longest Nice Subarray/README_EN.md
index fc16f9f6281cd..43cdbfe845a72 100644
--- a/solution/2400-2499/2401.Longest Nice Subarray/README_EN.md
+++ b/solution/2400-2499/2401.Longest Nice Subarray/README_EN.md
@@ -44,6 +44,22 @@ It can be proven that no longer nice subarray can be obtained, so we return 3.
## Solutions
+**Solution 1: Two Pointers**
+
+We define a variable $mask$ to record the bitwise OR result of the elements in the current subarray, initially $mask = 0$. Also, we use two pointers $j$ and $i$ to point to the left and right endpoints of the current subarray, initially $i = j = 0$.
+
+Next, we traverse the array $nums$ from left to right. For each element $x$ we encounter:
+
+We perform a bitwise AND operation between it and $mask$. If the result is not $0$, it means that $x$ and at least one element in $mask$ have a binary representation where a certain bit is $1$, and the corresponding bit in the other element's binary representation is $0$. Such pairs of elements cannot satisfy the problem's requirements, so we need to move $j$ to the right until the bitwise AND result of $x$ and $mask$ is $0$.
+
+At this point, we have found a subarray that satisfies the problem's requirements. Its length is $i - j + 1$. We compare it with the length of the current longest elegant subarray. If it is longer than the current longest elegant subarray, we update the length of the longest elegant subarray.
+
+Then we perform a bitwise OR operation between $mask$ and $x$, and continue to the next element.
+
+Finally, the length of the longest elegant subarray we obtain is the answer.
+
+The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2402.Meeting Rooms III/README.md b/solution/2400-2499/2402.Meeting Rooms III/README.md
index b32e6029a4294..a6c23fbc97b83 100644
--- a/solution/2400-2499/2402.Meeting Rooms III/README.md
+++ b/solution/2400-2499/2402.Meeting Rooms III/README.md
@@ -71,7 +71,7 @@
**方法一:优先队列(小根堆)**
-定义两个优先队列,分别表示空闲会议室、使用中的会议室。其中:空闲会议室 `idle` 依据**下标**排序;而使用中的会议室 `busy` 依据**结束时间、下标**排序。
+我们定义两个优先队列,分别表示空闲会议室、使用中的会议室。其中:空闲会议室 `idle` 依据**下标**排序;而使用中的会议室 `busy` 依据**结束时间、下标**排序。
先对会议按照开始时间排序,然后遍历会议,对于每个会议:
@@ -79,9 +79,11 @@
- 若当前有空闲会议室,那么在空闲队列 `idle` 中取出权重最小的会议室,将其加入使用中的队列 `busy` 中;
- 若当前没有空闲会议室,那么在使用队列 `busy` 中找出最早结束时间且下标最小的会议室,重新加入使用中的队列 `busy` 中。
-时间复杂度 $O(m\log m)$,其中 $m$ 为会议数量。
+时间复杂度 $O(m \times \log m)$,其中 $m$ 为会议数量。
-相似题目:[1882. 使用服务器处理任务](/solution/1800-1899/1882.Process%20Tasks%20Using%20Servers/README.md)
+相似题目:
+
+- [1882. 使用服务器处理任务](/solution/1800-1899/1882.Process%20Tasks%20Using%20Servers/README.md)
diff --git a/solution/2400-2499/2402.Meeting Rooms III/README_EN.md b/solution/2400-2499/2402.Meeting Rooms III/README_EN.md
index e261f43f2c56d..1183de90994c9 100644
--- a/solution/2400-2499/2402.Meeting Rooms III/README_EN.md
+++ b/solution/2400-2499/2402.Meeting Rooms III/README_EN.md
@@ -65,6 +65,22 @@ Room 0 held 1 meeting while rooms 1 and 2 each held 2 meetings, so we return 1.
## Solutions
+**Solution 1: Priority Queue (Min Heap)**
+
+We define two priority queues, representing idle meeting rooms and busy meeting rooms, respectively. Among them: the idle meeting rooms `idle` are sorted according to **index**; while the busy meeting rooms `busy` are sorted according to **end time, index**.
+
+First, sort the meetings by start time, then traverse the meetings. For each meeting:
+
+- If there is a busy meeting room that is less than or equal to the start time of the current meeting, add it to the idle meeting room queue `idle`.
+- If there are currently idle meeting rooms, take out the meeting room with the smallest weight from the idle queue `idle` and add it to the busy queue `busy`.
+- If there are currently no idle meeting rooms, find the meeting room with the earliest end time and smallest index in the busy queue `busy`, and re-add it to the busy queue `busy`.
+
+The time complexity is $O(m \times \log m)$, where $m$ is the number of meetings.
+
+Similar problems:
+
+- [1882. Process Tasks Using Servers](/solution/1800-1899/1882.Process%20Tasks%20Using%20Servers/README_EN.md)
+
### **Python3**
diff --git a/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README.md b/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README.md
index 65848bc563006..49e14eb00eed1 100644
--- a/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README.md
+++ b/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README.md
@@ -79,13 +79,13 @@
-**方法一:状态压缩 + 记忆化搜索/动态规划**
+**方法一:状态压缩 + 记忆化搜索或动态规划**
-由于打怪才能增加每天法力的收益 `gain`,不同的打怪顺序对结果有影响,需要枚举。注意到题目的数据范围较小,考虑使用状态压缩动态规划求解。
+由于打怪才能增加每天法力的收益 $gain$,不同的打怪顺序对结果有影响,需要枚举。注意到题目的数据范围较小,考虑使用状态压缩动态规划求解。
-我们定义状态 `mask` 表示当前已经打怪的情况,其二进制中的 `1` 表示已经被打倒的怪物,`0` 表示未被打倒的怪物。
+我们定义状态 $mask$ 表示当前已经打怪的情况,其二进制中的 $1$ 表示已经被打倒的怪物,而 $0$ 表示未被打倒的怪物。
-时间复杂度 $O(n\times 2^n)$,空间复杂度 $O(2^n)$。其中 $n$ 是怪物数量。
+时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(2^n)$。其中 $n$ 是怪物数量。
diff --git a/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README_EN.md b/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README_EN.md
index 850f22175d0d9..cf440b3ba3378 100644
--- a/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README_EN.md
+++ b/solution/2400-2499/2403.Minimum Time to Kill All Monsters/README_EN.md
@@ -69,6 +69,14 @@ It can be proven that 6 is the minimum number of days needed.
## Solutions
+**Solution 1: State Compression + Memorization Search or Dynamic Programming**
+
+Since defeating monsters can increase the daily magic power gain $gain$, the order of defeating monsters affects the result, so we need to enumerate. Noting that the data range of the problem is small, we consider using state compression dynamic programming to solve it.
+
+We define a state $mask$ to represent the current situation of defeating monsters. In its binary representation, $1$ represents the monsters that have been defeated, and $0$ represents the monsters that have not been defeated.
+
+The time complexity is $O(n \times 2^n)$, and the space complexity is $O(2^n)$. Here, $n$ is the number of monsters.
+
### **Python3**
diff --git a/solution/2400-2499/2404.Most Frequent Even Element/README_EN.md b/solution/2400-2499/2404.Most Frequent Even Element/README_EN.md
index 4594daeee7fc3..527fee2da5b77 100644
--- a/solution/2400-2499/2404.Most Frequent Even Element/README_EN.md
+++ b/solution/2400-2499/2404.Most Frequent Even Element/README_EN.md
@@ -44,6 +44,12 @@ We return the smallest one, which is 2.
## Solutions
+**Solution 1: Hash Table**
+
+We use a hash table $cnt$ to count the occurrence of all even elements, and then find the even element with the highest occurrence and the smallest value.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2405.Optimal Partition of String/README.md b/solution/2400-2499/2405.Optimal Partition of String/README.md
index 878c9c69b4fed..5057e8506aa37 100644
--- a/solution/2400-2499/2405.Optimal Partition of String/README.md
+++ b/solution/2400-2499/2405.Optimal Partition of String/README.md
@@ -52,7 +52,7 @@
过程中,可以用哈希表记录当前子字符串的所有字符,空间复杂度 $O(n)$;也可以使用一个数字,用位运算的方式记录字符,空间复杂度 $O(1)$。
-时间复杂度 $O(n)$。其中 $n$ 是字符串 `s` 的长度。
+时间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。
diff --git a/solution/2400-2499/2405.Optimal Partition of String/README_EN.md b/solution/2400-2499/2405.Optimal Partition of String/README_EN.md
index b204223ec03f1..feeb5c105e41e 100644
--- a/solution/2400-2499/2405.Optimal Partition of String/README_EN.md
+++ b/solution/2400-2499/2405.Optimal Partition of String/README_EN.md
@@ -40,6 +40,14 @@ It can be shown that 4 is the minimum number of substrings needed.
## Solutions
+**Solution 1: Greedy**
+
+According to the problem, each substring should be as long as possible and contain unique characters. We just need to partition greedily.
+
+During the process, we can use a hash table to record all characters in the current substring, with a space complexity of $O(n)$; or we can use a number to record characters using bitwise operations, with a space complexity of $O(1)$.
+
+The time complexity is $O(n)$, where $n$ is the length of the string $s$.
+
### **Python3**
diff --git a/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README.md b/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README.md
index e1cf506deb7ce..1b2f19ac770bd 100644
--- a/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README.md
+++ b/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README.md
@@ -51,12 +51,14 @@
**方法一:贪心 + 优先队列(小根堆)**
-先将区间按左端点排序,用小根堆维护每组的最右端点(堆顶是所有组的最右端点的最小值)。遍历每个区间:
+我们先将区间按左端点排序,用小根堆维护每组的最右端点(堆顶是所有组的最右端点的最小值)。
+
+接下来,我们遍历每个区间:
- 若当前区间左端点大于堆顶元素,说明当前区间可以加入到堆顶元素所在的组中,我们直接弹出堆顶元素,然后将当前区间的右端点放入堆中;
- 否则,说明当前没有组能容纳当前区间,那么我们就新建一个组,将当前区间的右端点放入堆中。
-时间复杂度 $O(n\log n)$。其中 $n$ 是数组 `intervals` 的长度。
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `intervals` 的长度。
diff --git a/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README_EN.md b/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README_EN.md
index 8b60069b974fb..85c700ac15a1e 100644
--- a/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README_EN.md
+++ b/solution/2400-2499/2406.Divide Intervals Into Minimum Number of Groups/README_EN.md
@@ -44,6 +44,17 @@ It can be proven that it is not possible to divide the intervals into fewer than
## Solutions
+**Solution 1: Greedy + Priority Queue (Min Heap)**
+
+First, we sort the intervals by their left endpoints. We use a min heap to maintain the rightmost endpoint of each group (the top of the heap is the minimum of the rightmost endpoints of all groups).
+
+Next, we traverse each interval:
+
+- If the left endpoint of the current interval is greater than the top element of the heap, it means the current interval can be added to the group where the top element of the heap is located. We directly pop the top element of the heap, and then put the right endpoint of the current interval into the heap.
+- Otherwise, it means there is currently no group that can accommodate the current interval, so we create a new group and put the right endpoint of the current interval into the heap.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array `intervals`.
+
### **Python3**
diff --git a/solution/2400-2499/2407.Longest Increasing Subsequence II/README.md b/solution/2400-2499/2407.Longest Increasing Subsequence II/README.md
index 18e6569975d42..26a132331ed9f 100644
--- a/solution/2400-2499/2407.Longest Increasing Subsequence II/README.md
+++ b/solution/2400-2499/2407.Longest Increasing Subsequence II/README.md
@@ -64,9 +64,9 @@
**方法一:线段树**
-我们假设 `f[v]` 表示以数字 $v$ 结尾的最长递增子序列的长度。
+我们假设 $f[v]$ 表示以数字 $v$ 结尾的最长递增子序列的长度。
-我们遍历数组 `nums` 中的每个元素 $v$,有状态转移方程:`f[v]=max(f[v], f[x])`,其中 $x$ 的取值范围是 $[v-k, v-1]$。
+我们遍历数组 $nums$ 中的每个元素 $v$,有状态转移方程:$f[v] = \max(f[v], f[x])$,其中 $x$ 的取值范围是 $[v-k, v-1]$。
因此,我们需要一个数据结构,来维护区间的最大值,不难想到使用线段树。
@@ -79,7 +79,7 @@
对于本题,线段树节点维护的信息是区间范围内的最大值。
-时间复杂度 $O(n\log n)$。其中 $n$ 是数组 `nums` 的长度。
+时间复杂度 $O(n \times \log n)$。其中 $n$ 是数组 $nums$ 的长度。
diff --git a/solution/2400-2499/2407.Longest Increasing Subsequence II/README_EN.md b/solution/2400-2499/2407.Longest Increasing Subsequence II/README_EN.md
index 90eddd4651b53..e53197a25fd5d 100644
--- a/solution/2400-2499/2407.Longest Increasing Subsequence II/README_EN.md
+++ b/solution/2400-2499/2407.Longest Increasing Subsequence II/README_EN.md
@@ -59,6 +59,25 @@ The subsequence has a length of 1, so we return 1.
## Solutions
+**Solution 1: Segment Tree**
+
+We assume that $f[v]$ represents the length of the longest increasing subsequence ending with the number $v$.
+
+We traverse each element $v$ in the array $nums$, with the state transition equation: $f[v] = \max(f[v], f[x])$, where the range of $x$ is $[v-k, v-1]$.
+
+Therefore, we need a data structure to maintain the maximum value of the interval. It is not difficult to think of using a segment tree.
+
+The segment tree divides the entire interval into multiple discontinuous subintervals, and the number of subintervals does not exceed $log(width)$. To update the value of an element, only $log(width)$ intervals need to be updated, and these intervals are all contained in a large interval that contains the element.
+
+- Each node of the segment tree represents an interval;
+- The segment tree has a unique root node, which represents the entire statistical range, such as $[1,N]$;
+- Each leaf node of the segment tree represents an elementary interval of length $1$, $[x, x]$;
+- For each internal node $[l,r]$, its left child is $[l,mid]$, and the right child is $[mid+1,r]$, where $mid = \left \lfloor \frac{l+r}{2} \right \rfloor$.
+
+For this problem, the information maintained by the segment tree node is the maximum value within the interval range.
+
+The time complexity is $O(n \times \log n)$, where $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2408.Design SQL/README_EN.md b/solution/2400-2499/2408.Design SQL/README_EN.md
index 1047839169a4a..1bd8a9e75efd3 100644
--- a/solution/2400-2499/2408.Design SQL/README_EN.md
+++ b/solution/2400-2499/2408.Design SQL/README_EN.md
@@ -61,6 +61,12 @@ sql.selectCell("two", 2, 2); // return "fifth", finds the va
## Solutions
+**Solution 1: Hash Table**
+
+Create a hash table `tables` to store the mapping of table names to table data rows. Directly simulate the operations in the problem.
+
+The time complexity of each operation is $O(1)$, and the space complexity is $O(n)$.
+
### **Python3**
diff --git a/solution/2400-2499/2409.Count Days Spent Together/README_EN.md b/solution/2400-2499/2409.Count Days Spent Together/README_EN.md
index 11cc9e7b4b23a..83d4d2738af22 100644
--- a/solution/2400-2499/2409.Count Days Spent Together/README_EN.md
+++ b/solution/2400-2499/2409.Count Days Spent Together/README_EN.md
@@ -40,6 +40,12 @@
## Solutions
+**Solution 1: Simulation**
+
+We convert the dates into days, and then calculate the number of days both people are in Rome.
+
+The time complexity is $O(C)$, and the space complexity is $O(C)$. Here, $C$ is a constant.
+
### **Python3**
diff --git a/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README.md b/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README.md
index 747c277ebf8ab..411592b36335e 100644
--- a/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README.md
+++ b/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README.md
@@ -51,7 +51,7 @@
按运动员的能力值从小到大排序,选择大于等于运动员能力值的,且自身能力值最小的训练师。
-时间复杂度 $O(n\log n + m\log m)$。其中 $n$, $m$ 分别为运动员和训练师的数量。
+时间复杂度 $O(n \times \log n + m \times \log m)$,空间复杂度 $O(\log n + \log m)$。其中 $n$ 和 $m$ 分别为运动员和训练师的数量。
diff --git a/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README_EN.md b/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README_EN.md
index ed1d3ad5125eb..79531c197ad57 100644
--- a/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README_EN.md
+++ b/solution/2400-2499/2410.Maximum Matching of Players With Trainers/README_EN.md
@@ -43,6 +43,12 @@ Each player can only be matched with one trainer, so the maximum answer is 1.
## Solutions
+**Solution 1: Greedy + Two Pointers**
+
+Sort the athletes by their abilities in ascending order, and select the trainer with the smallest ability that is greater than or equal to the athlete's ability.
+
+The time complexity is $O(n \times \log n + m \times \log m)$, and the space complexity is $O(\log n + \log m)$. Here, $n$ and $m$ are the number of athletes and trainers, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README.md b/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README.md
index 7c60ad51c6bf6..4f2882def9f2d 100644
--- a/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README.md
+++ b/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README.md
@@ -64,9 +64,9 @@
我们用一个 $32$ 位大小的数组$f$ 来记录每一位 $1$ 最早出现的位置。
-逆序遍历数组 `nums[i]`,对于 `nums[i]` 数字中的第 $j$ 位,如果为 $1$,那么 $f[j]$ 就是 $i$。否则如果 $f[j]$ 不为 $-1$,说明右侧找到了满足第 $j$ 位为 $1$ 的数字,更新长度。
+逆序遍历数组 $nums[i]$,对于 $nums[i]$ 数字中的第 $j$ 位,如果为 $1$,那么 $f[j]$ 就是 $i$。否则如果 $f[j]$ 不为 $-1$,说明右侧找到了满足第 $j$ 位为 $1$ 的数字,更新长度。
-时间复杂度 $O(n\log m)$。其中 $n$ 为数组 `nums` 的长度,而 $m$ 为数组 `nums` 中的最大值。
+时间复杂度 $O(n \times \log m)$。其中 $n$ 为数组 $nums$ 的长度,而 $m$ 为数组 $nums$ 中的最大值。
diff --git a/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README_EN.md b/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README_EN.md
index e49ee53196d16..bc5e6b9be4c2f 100644
--- a/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README_EN.md
+++ b/solution/2400-2499/2411.Smallest Subarrays With Maximum Bitwise OR/README_EN.md
@@ -54,6 +54,16 @@ Therefore, we return [2,1].
## Solutions
+**Solution 1: Reverse Traversal**
+
+To find the shortest subarray starting at position $i$ that maximizes the bitwise OR operation, we need to maximize the number of $1$s in the result.
+
+We use an array $f$ of size $32$ to record the earliest position of each bit $1$.
+
+We traverse the array $nums[i]$ in reverse order. For the $j$-th bit of $nums[i]$, if it is $1$, then $f[j]$ is $i$. Otherwise, if $f[j]$ is not $-1$, it means that a number satisfying the $j$-th bit as $1$ is found on the right, so we update the length.
+
+The time complexity is $O(n \times \log m)$, where $n$ is the length of the array $nums$, and $m$ is the maximum value in the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2412.Minimum Money Required Before Transactions/README.md b/solution/2400-2499/2412.Minimum Money Required Before Transactions/README.md
index 64c7d22d0e844..88d45571aa736 100644
--- a/solution/2400-2499/2412.Minimum Money Required Before Transactions/README.md
+++ b/solution/2400-2499/2412.Minimum Money Required Before Transactions/README.md
@@ -51,9 +51,9 @@
**方法一:贪心**
-先累计所有负收益,我们记为 $s$。然后枚举每个交易作为最后一个交易,如果 `transactions[i].x > transactions[i].y`,说明当前的交易是亏钱的,而这个交易在此前我们累计负收益的时候,已经被计算,因此取 `s + transactions[i].y` 更新答案;否则,取 `s + transactions[i].x` 更新答案。
+我们先累计所有负收益,记为 $s$。然后枚举每个交易作为最后一个交易,如果 `transactions[i].x > transactions[i].y`,说明当前的交易是亏钱的,而这个交易在此前我们累计负收益的时候,已经被计算,因此取 `s + transactions[i].y` 更新答案;否则,取 `s + transactions[i].x` 更新答案。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为交易数。
+时间复杂度 $O(n)$,其中 $n$ 为交易数。空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2412.Minimum Money Required Before Transactions/README_EN.md b/solution/2400-2499/2412.Minimum Money Required Before Transactions/README_EN.md
index f710377ded1dd..3bfaf0ce2f6c9 100644
--- a/solution/2400-2499/2412.Minimum Money Required Before Transactions/README_EN.md
+++ b/solution/2400-2499/2412.Minimum Money Required Before Transactions/README_EN.md
@@ -43,6 +43,12 @@ Thus, starting with money = 3, the transactions can be performed in any order.
## Solutions
+**Solution 1: Greedy**
+
+First, we accumulate all the negative profits, denoted as $s$. Then we enumerate each transaction as the last transaction. If `transactions[i].x > transactions[i].y`, it means the current transaction is losing money, and this transaction has been calculated when we previously accumulated negative profits, so we update the answer with `s + transactions[i].y`; otherwise, we update the answer with `s + transactions[i].x`.
+
+The time complexity is $O(n)$, where $n$ is the number of transactions. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2413.Smallest Even Multiple/README.md b/solution/2400-2499/2413.Smallest Even Multiple/README.md
index dcb2722f2e3b6..6adbd79957f33 100644
--- a/solution/2400-2499/2413.Smallest Even Multiple/README.md
+++ b/solution/2400-2499/2413.Smallest Even Multiple/README.md
@@ -38,7 +38,7 @@
**方法一:数学**
-如果 $n$ 为偶数,那么 $2$ 和 $n$ 的最小公倍数就是 $n$ 本身。否则,$2$ 和 $n$ 的最小公倍数就是 $n\times 2$。
+如果 $n$ 为偶数,那么 $2$ 和 $n$ 的最小公倍数就是 $n$ 本身。否则,$2$ 和 $n$ 的最小公倍数就是 $n \times 2$。
时间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2413.Smallest Even Multiple/README_EN.md b/solution/2400-2499/2413.Smallest Even Multiple/README_EN.md
index d24916d838df3..60235878714e7 100644
--- a/solution/2400-2499/2413.Smallest Even Multiple/README_EN.md
+++ b/solution/2400-2499/2413.Smallest Even Multiple/README_EN.md
@@ -32,6 +32,12 @@ Given a positive integer n
, return the smalles
## Solutions
+**Solution 1: Mathematics**
+
+If $n$ is even, then the least common multiple (LCM) of $2$ and $n$ is $n$ itself. Otherwise, the LCM of $2$ and $n$ is $n \times 2$.
+
+The time complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README.md b/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README.md
index 4b673b41401df..35a84b6f1309a 100644
--- a/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README.md
+++ b/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README.md
@@ -48,7 +48,7 @@
我们用双指针 $i$ 和 $j$ 分别指向当前连续子字符串的起始位置和结束位置。遍历字符串 $s$,如果当前字符 $s[j]$ 比 $s[j-1]$ 大,则 $j$ 向右移动一位,否则更新 $i$ 为 $j$,并更新最长连续子字符串的长度。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
+时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README_EN.md b/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README_EN.md
index 1a488b1f3079e..c9cb24a995fe0 100644
--- a/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README_EN.md
+++ b/solution/2400-2499/2414.Length of the Longest Alphabetical Continuous Substring/README_EN.md
@@ -40,6 +40,12 @@
## Solutions
+**Solution 1: Two Pointers**
+
+We use two pointers $i$ and $j$ to point to the start and end of the current consecutive substring respectively. Traverse the string $s$, if the current character $s[j]$ is greater than $s[j-1]$, then move $j$ one step to the right, otherwise update $i$ to $j$, and update the length of the longest consecutive substring.
+
+The time complexity is $O(n)$, where $n$ is the length of the string $s$. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README.md b/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README.md
index 84feecb99604d..5d46c170da3c0 100644
--- a/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README.md
+++ b/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README.md
@@ -68,7 +68,7 @@
然后遍历每个字符串,累加每个前缀的出现次数即可。
-时间复杂度 $O(n\times m)$。其中 $n$, $m$ 分别为字符串数组 `words` 的长度和其中字符串的最大长度。
+时间复杂度 $O(n \times m)$。其中 $n$, $m$ 分别为字符串数组 `words` 的长度和其中字符串的最大长度。
diff --git a/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README_EN.md b/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README_EN.md
index 333367b570a0e..177ed3396a2f6 100644
--- a/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README_EN.md
+++ b/solution/2400-2499/2416.Sum of Prefix Scores of Strings/README_EN.md
@@ -58,6 +58,14 @@ Each prefix has a score of one, so the total is answer[0] = 1 + 1 + 1 + 1 = 4.
## Solutions
+**Solution 1: Trie**
+
+Use a trie to maintain the prefixes of all strings and the occurrence count of each prefix.
+
+Then, traverse each string, accumulating the occurrence count of each prefix.
+
+The time complexity is $O(n \times m)$. Here, $n$ and $m$ are the length of the string array `words` and the maximum length of the strings in it, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2418.Sort the People/README_EN.md b/solution/2400-2499/2418.Sort the People/README_EN.md
index a0dc70304ebfe..52eb9d4525bd9 100644
--- a/solution/2400-2499/2418.Sort the People/README_EN.md
+++ b/solution/2400-2499/2418.Sort the People/README_EN.md
@@ -41,6 +41,14 @@
## Solutions
+**Solution 1: Sorting**
+
+According to the problem description, we can create an index array $idx$ of length $n$, where $idx[i]=i$. Then we sort each index in $idx$ in descending order according to the corresponding height in $heights$. Finally, we traverse each index $i$ in the sorted $idx$ and add $names[i]$ to the answer array.
+
+We can also create an array $arr$ of length $n$, where each element is a tuple $(heights[i], i)$. Then we sort $arr$ in descending order by height. Finally, we traverse each element $(heights[i], i)$ in the sorted $arr$ and add $names[i]$ to the answer array.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the arrays $names$ and $heights$.
+
### **Python3**
diff --git a/solution/2400-2499/2419.Longest Subarray With Maximum Bitwise AND/README_EN.md b/solution/2400-2499/2419.Longest Subarray With Maximum Bitwise AND/README_EN.md
index 2c72b6b3071b4..685cc0bcd5782 100644
--- a/solution/2400-2499/2419.Longest Subarray With Maximum Bitwise AND/README_EN.md
+++ b/solution/2400-2499/2419.Longest Subarray With Maximum Bitwise AND/README_EN.md
@@ -49,6 +49,16 @@ The longest subarray with that value is [4], so we return 1.
## Solutions
+**Solution 1: Quick Thinking**
+
+Due to the bitwise AND operation, the number will not get larger, so the maximum value is the maximum value in the array.
+
+The problem can be transformed into finding the maximum number of consecutive occurrences of the maximum value in the array.
+
+First, traverse the array once to find the maximum value, then traverse the array again to find the number of consecutive occurrences of the maximum value, and finally return this count.
+
+The time complexity is $O(n)$, where $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2420.Find All Good Indices/README.md b/solution/2400-2499/2420.Find All Good Indices/README.md
index c4645418cf2c9..98b03a3c66083 100644
--- a/solution/2400-2499/2420.Find All Good Indices/README.md
+++ b/solution/2400-2499/2420.Find All Good Indices/README.md
@@ -54,11 +54,11 @@
**方法一:递推**
-定义两个数组 `decr` 和 `incr`,分别表示从左到右和从右到左的非递增和非递减的最长子数组长度。
+我们定义两个数组 `decr` 和 `incr`,分别表示从左到右和从右到左的非递增和非递减的最长子数组长度。
遍历数组,更新 `decr` 和 `incr` 数组。
-然后顺序遍历下标 $i$(其中 $k\le i \lt n - k$),若 `decr[i] >= k && incr[i] >= k`,则 `i` 为好下标。
+然后顺序遍历下标 $i$(其中 $k\le i \lt n - k$),若 $decr[i] \geq k$ 并且 $incr[i] \geq k$,则 $i$ 为好下标。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组长度。
diff --git a/solution/2400-2499/2420.Find All Good Indices/README_EN.md b/solution/2400-2499/2420.Find All Good Indices/README_EN.md
index 8c1ca30745855..3716404e0b80b 100644
--- a/solution/2400-2499/2420.Find All Good Indices/README_EN.md
+++ b/solution/2400-2499/2420.Find All Good Indices/README_EN.md
@@ -46,6 +46,16 @@ Note that the index 4 is not good because [4,1] is not non-decreasing.
## Solutions
+**Solution 1: Recursion**
+
+We define two arrays `decr` and `incr`, which represent the longest non-increasing and non-decreasing subarray lengths from left to right and from right to left, respectively.
+
+We traverse the array, updating the `decr` and `incr` arrays.
+
+Then we sequentially traverse the index $i$ (where $k\le i \lt n - k$), if $decr[i] \geq k$ and $incr[i] \geq k$, then $i$ is a good index.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2421.Number of Good Paths/README.md b/solution/2400-2499/2421.Number of Good Paths/README.md
index 42b3382b6b0f2..13f3165b7f0bb 100644
--- a/solution/2400-2499/2421.Number of Good Paths/README.md
+++ b/solution/2400-2499/2421.Number of Good Paths/README.md
@@ -79,7 +79,7 @@
当遍历到点 $a$ 时, 对于小于等于 $vals[a]$ 的邻接点 $b$ 来说,若二者不在同一个连通块,则可以合并,并且可以以点 $a$ 所在的连通块中所有值为 $vals[a]$ 的点为起点,以点 $b$ 所在的连通块中所有值为 $vals[a]$ 的点为终点,两种点的个数的乘积即为加入点 $a$ 时对答案的贡献。
-时间复杂度 $O(n\log n)$。
+时间复杂度 $O(n \times \log n)$。
diff --git a/solution/2400-2499/2421.Number of Good Paths/README_EN.md b/solution/2400-2499/2421.Number of Good Paths/README_EN.md
index 3140acb374624..85b3d03e07a33 100644
--- a/solution/2400-2499/2421.Number of Good Paths/README_EN.md
+++ b/solution/2400-2499/2421.Number of Good Paths/README_EN.md
@@ -64,6 +64,14 @@ There are 2 additional good paths: 0 -> 1 and 2 -> 3.
## Solutions
+**Solution 1: Sorting + Union Find**
+
+To ensure that the starting point (or endpoint) of the path is greater than or equal to all points on the path, we can consider sorting all points from small to large first, then traverse and add them to the connected component, specifically as follows:
+
+When traversing to point $a$, for the adjacent point $b$ that is less than or equal to $vals[a]$, if they are not in the same connected component, they can be merged. And we can use all points in the connected component where point $a$ is located with a value of $vals[a]$ as the starting point, and all points in the connected component where point $b$ is located with a value of $vals[a]$ as the endpoint. The product of the number of the two types of points is the contribution to the answer when adding point $a$.
+
+The time complexity is $O(n \times \log n)$.
+
### **Python3**
diff --git a/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README.md b/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README.md
index 70c515b8aa5ea..28e5406bce88f 100644
--- a/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README.md
+++ b/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README.md
@@ -12,12 +12,10 @@
- 选择任意两个 相邻 的元素并用它们的 和 替换 它们。
-
- 例如,如果
nums = [1,2,3,1]
,则可以应用一个操作使其变为 [1,5,1]
。
-
返回将数组转换为 回文序列 所需的 最小 操作数。
@@ -69,7 +67,7 @@
循环上述过程,直至指针 $i \ge j$,返回操作次数 $ans$ 即可。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。
+时间复杂度 $O(n)$,其中 $n$ 为数组的长度。空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README_EN.md b/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README_EN.md
index 0cc76244b6762..8c3762c4a9e5e 100644
--- a/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README_EN.md
+++ b/solution/2400-2499/2422.Merge Operations to Turn Array Into a Palindrome/README_EN.md
@@ -10,12 +10,10 @@
- Choose any two adjacent elements and replace them with their sum.
-
- For example, if
nums = [1,2,3,1]
, you can apply one operation to make it [1,5,1]
.
-
Return the minimum number of operations needed to turn the array into a palindrome.
@@ -51,6 +49,20 @@ It can be shown that 2 is the minimum number of operations needed.
## Solutions
+**Solution 1: Greedy + Two Pointers**
+
+Define two pointers $i$ and $j$, pointing to the beginning and end of the array respectively, use variables $a$ and $b$ to represent the values of the first and last elements, and variable $ans$ to represent the number of operations.
+
+If $a < b$, we move the pointer $i$ one step to the right, i.e., $i \leftarrow i + 1$, then add the value of the element pointed to by $i$ to $a$, i.e., $a \leftarrow a + nums[i]$, and increment the operation count by one, i.e., $ans \leftarrow ans + 1$.
+
+If $a > b$, we move the pointer $j$ one step to the left, i.e., $j \leftarrow j - 1$, then add the value of the element pointed to by $j$ to $b$, i.e., $b \leftarrow b + nums[j]$, and increment the operation count by one, i.e., $ans \leftarrow ans + 1$.
+
+Otherwise, it means $a = b$, at this time we move the pointer $i$ one step to the right, i.e., $i \leftarrow i + 1$, move the pointer $j$ one step to the left, i.e., $j \leftarrow j - 1$, and update the values of $a$ and $b$, i.e., $a \leftarrow nums[i]$ and $b \leftarrow nums[j]$.
+
+Repeat the above process until $i \ge j$, return the operation count $ans$.
+
+The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2423.Remove Letter To Equalize Frequency/README_EN.md b/solution/2400-2499/2423.Remove Letter To Equalize Frequency/README_EN.md
index 7721efc701e67..52895bcf6d1e6 100644
--- a/solution/2400-2499/2423.Remove Letter To Equalize Frequency/README_EN.md
+++ b/solution/2400-2499/2423.Remove Letter To Equalize Frequency/README_EN.md
@@ -42,6 +42,16 @@
## Solutions
+**Solution 1: Counting + Enumeration**
+
+First, we use a hash table or an array of length $26$ named $cnt$ to count the number of occurrences of each letter in the string.
+
+Next, we enumerate the $26$ letters. If letter $c$ appears in the string, we decrement its count by one, then check whether the counts of the remaining letters are the same. If they are, return `true`. Otherwise, increment the count of $c$ by one and continue to enumerate the next letter.
+
+If the enumeration ends, it means that it is impossible to make the counts of the remaining letters the same by deleting one letter, so return `false`.
+
+The time complexity is $O(n + C^2)$, and the space complexity is $O(C)$. Here, $n$ is the length of the string $word$, and $C$ is the size of the character set. In this problem, $C = 26$.
+
### **Python3**
diff --git a/solution/2400-2499/2424.Longest Uploaded Prefix/README_EN.md b/solution/2400-2499/2424.Longest Uploaded Prefix/README_EN.md
index 1510fc3eadf9c..77eff34cc54ad 100644
--- a/solution/2400-2499/2424.Longest Uploaded Prefix/README_EN.md
+++ b/solution/2400-2499/2424.Longest Uploaded Prefix/README_EN.md
@@ -50,6 +50,14 @@ server.longest(); // The prefix [1,2,3] is the longest upload
## Solutions
+**Solution 1: Simulation**
+
+We use a variable $r$ to record the current longest prefix of uploaded videos, and an array or hash table $s$ to record the videos that have been uploaded.
+
+Each time a video is uploaded, we set `s[video]` to `true`, then loop to check whether `s[r + 1]` is `true`. If it is, we update $r$.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the total number of videos.
+
### **Python3**
diff --git a/solution/2400-2499/2425.Bitwise XOR of All Pairings/README.md b/solution/2400-2499/2425.Bitwise XOR of All Pairings/README.md
index 401fb15b4cf95..f4373f2285402 100644
--- a/solution/2400-2499/2425.Bitwise XOR of All Pairings/README.md
+++ b/solution/2400-2499/2425.Bitwise XOR of All Pairings/README.md
@@ -46,7 +46,7 @@
**方法一:脑筋急转弯 + 位运算**
-由于数组的每个元素都会与另一个数组的每个元素进行异或,我们知道,同一个数异或两次,结果不变,即 `a ^ a = 0`。因此,我们只需要统计数组的长度,就能知道每个元素与另一个数组的每个元素进行异或的次数。
+由于数组的每个元素都会与另一个数组的每个元素进行异或,我们知道,同一个数异或两次,结果不变,即 $a \oplus a = 0$。因此,我们只需要统计数组的长度,就能知道每个元素与另一个数组的每个元素进行异或的次数。
如果 `nums2` 数组长度为奇数,那么相当于 `nums1` 中每个元素都与 `nums2` 中的每个元素进行了奇数次异或,因此 `nums1` 数组的最终异或结果即为 `nums1` 数组的所有元素异或的结果。如果为偶数,那么相当于 `nums1` 中每个元素都与 `nums2` 中的每个元素进行了偶数次异或,因此 `nums1` 数组的最终异或结果为 0。
diff --git a/solution/2400-2499/2425.Bitwise XOR of All Pairings/README_EN.md b/solution/2400-2499/2425.Bitwise XOR of All Pairings/README_EN.md
index 0c13e1eda14ff..cd6de44325108 100644
--- a/solution/2400-2499/2425.Bitwise XOR of All Pairings/README_EN.md
+++ b/solution/2400-2499/2425.Bitwise XOR of All Pairings/README_EN.md
@@ -41,6 +41,18 @@ Thus, one possible nums3 array is [2,5,1,6].
## Solutions
+**Solution 1: Quick Thinking + Bit Manipulation**
+
+Since each element of the array will be XORed with each element of another array, we know that the result remains the same when the same number is XORed twice, i.e., $a \oplus a = 0$. Therefore, we only need to count the length of the array to know how many times each element is XORed with each element of another array.
+
+If the length of the `nums2` array is odd, it means that each element in `nums1` has been XORed an odd number of times with each element in `nums2`, so the final XOR result of the `nums1` array is the XOR result of all elements in the `nums1` array. If it is even, it means that each element in `nums1` has been XORed an even number of times with each element in `nums2`, so the final XOR result of the `nums1` array is 0.
+
+Similarly, we can know the final XOR result of the `nums2` array.
+
+Finally, XOR the two results again to get the final result.
+
+The time complexity is $O(m+n)$. Where $m$ and $n$ are the lengths of the `nums1` and `nums2` arrays, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README.md b/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README.md
index 9fd2f58b500a5..6ae874fa4d26b 100644
--- a/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README.md
+++ b/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README.md
@@ -54,11 +54,11 @@
**方法一:树状数组**
-我们将题目的不等式转换一下,得到 `nums1[i] - nums2[i] <= nums1[j] - nums2[j] + diff`,因此,如果我们对两个数组对应位置的元素求差值,得到另一个数组 `nums`,那么题目就转换为求 `nums` 中满足 `nums[i] <= nums[j] + diff` 的数对数目。
+我们将题目的不等式转换一下,得到 $nums1[i] - nums2[i] \leq nums1[j] - nums2[j] + diff$,因此,如果我们对两个数组对应位置的元素求差值,得到另一个数组 $nums$,那么题目就转换为求 $nums$ 中满足 $nums[i] \leq nums[j] + diff$ 的数对数目。
-我们可以从小到大枚举 $j$,找出前面有多少个数满足 `nums[i] <= nums[j] + diff`,这样就可以求出数对数目。我们可以使用树状数组来维护前缀和,这样就可以在 $O(\log n)$ 的时间内求出前面有多少个数满足 `nums[i] <= nums[j] + diff`。
+我们可以从小到大枚举 $j$,找出前面有多少个数满足 $nums[i] \leq nums[j] + diff$,这样就可以求出数对数目。我们可以使用树状数组来维护前缀和,这样就可以在 $O(\log n)$ 的时间内求出前面有多少个数满足 $nums[i] \leq nums[j] + diff$。
-时间复杂度 $O(n\log n)$。
+时间复杂度 $O(n \times \log n)$。
diff --git a/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README_EN.md b/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README_EN.md
index e13f27ed59b1f..50c2c472a2ace 100644
--- a/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README_EN.md
+++ b/solution/2400-2499/2426.Number of Pairs Satisfying Inequality/README_EN.md
@@ -48,6 +48,14 @@ Since there does not exist any pair that satisfies the conditions, we return 0.
## Solutions
+**Solution 1: Binary Indexed Tree**
+
+We can transform the inequality in the problem to $nums1[i] - nums2[i] \leq nums1[j] - nums2[j] + diff$. Therefore, if we calculate the difference between the corresponding elements of the two arrays and get another array $nums$, the problem is transformed into finding the number of pairs in $nums$ that satisfy $nums[i] \leq nums[j] + diff$.
+
+We can enumerate $j$ from small to large, find out how many numbers before it satisfy $nums[i] \leq nums[j] + diff$, and thus calculate the number of pairs. We can use a binary indexed tree to maintain the prefix sum, so we can find out how many numbers before it satisfy $nums[i] \leq nums[j] + diff$ in $O(\log n)$ time.
+
+The time complexity is $O(n \times \log n)$.
+
### **Python3**
diff --git a/solution/2400-2499/2427.Number of Common Factors/README_EN.md b/solution/2400-2499/2427.Number of Common Factors/README_EN.md
index d13cd344705f4..9dc6f6e10e163 100644
--- a/solution/2400-2499/2427.Number of Common Factors/README_EN.md
+++ b/solution/2400-2499/2427.Number of Common Factors/README_EN.md
@@ -34,6 +34,18 @@
## Solutions
+**Solution 1: Enumeration**
+
+We can first calculate the greatest common divisor $g$ of $a$ and $b$, then enumerate each number in $[1,..g]$, check whether it is a factor of $g$, if it is, then increment the answer by one.
+
+The time complexity is $O(\min(a, b))$, and the space complexity is $O(1)$.
+
+**Solution 2: Optimized Enumeration**
+
+Similar to Solution 1, we can first calculate the greatest common divisor $g$ of $a$ and $b$, then enumerate all factors of the greatest common divisor $g$, and accumulate the answer.
+
+The time complexity is $O(\sqrt{\min(a, b)})$, and the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2428.Maximum Sum of an Hourglass/README.md b/solution/2400-2499/2428.Maximum Sum of an Hourglass/README.md
index 0933f61ed3f1a..88e6b83cae3b1 100644
--- a/solution/2400-2499/2428.Maximum Sum of an Hourglass/README.md
+++ b/solution/2400-2499/2428.Maximum Sum of an Hourglass/README.md
@@ -49,7 +49,7 @@
我们观察题目发现,每个沙漏就是一个 $3 \times 3$ 的矩阵挖去中间行的首尾两个元素。因此,我们可以从左上角开始,枚举每个沙漏的中间坐标 $(i, j)$,然后计算沙漏的元素和,取其中的最大值即可。
-时间复杂度 $O(m \times n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
+时间复杂度 $O(m \times n)$,其中 $m$ 和 $n$ 分别是矩阵的行数和列数。空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2428.Maximum Sum of an Hourglass/README_EN.md b/solution/2400-2499/2428.Maximum Sum of an Hourglass/README_EN.md
index 45e9e44bcca55..18b03ec3ad97c 100644
--- a/solution/2400-2499/2428.Maximum Sum of an Hourglass/README_EN.md
+++ b/solution/2400-2499/2428.Maximum Sum of an Hourglass/README_EN.md
@@ -41,6 +41,12 @@
## Solutions
+**Solution 1: Enumeration**
+
+We observe from the problem statement that each hourglass is a $3 \times 3$ matrix with the first and last elements of the middle row removed. Therefore, we can start from the top left corner, enumerate the middle coordinate $(i, j)$ of each hourglass, then calculate the sum of the elements in the hourglass, and take the maximum value.
+
+The time complexity is $O(m \times n)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2429.Minimize XOR/README_EN.md b/solution/2400-2499/2429.Minimize XOR/README_EN.md
index 5bcbe4e244af2..999dced728a28 100644
--- a/solution/2400-2499/2429.Minimize XOR/README_EN.md
+++ b/solution/2400-2499/2429.Minimize XOR/README_EN.md
@@ -47,6 +47,12 @@ The integer 3 has the same number of set bits as num2, and the
## Solutions
+**Solution 1: Greedy + Bit Manipulation**
+
+According to the problem description, we first calculate the number of set bits $cnt$ in $num2$, then enumerate each bit of $num1$ from high to low. If the bit is $1$, we set the corresponding bit in $x$ to $1$ and decrement $cnt$ by $1$, until $cnt$ is $0$. If $cnt$ is still not $0$ at this point, we start from the low bit and set each bit of $num1$ that is $0$ to $1$, and decrement $cnt$ by $1$, until $cnt$ is $0$.
+
+The time complexity is $O(\log n)$, and the space complexity is $O(1)$. Here, $n$ is the maximum value of $num1$ and $num2$.
+
### **Python3**
diff --git a/solution/2400-2499/2430.Maximum Deletions on a String/README_EN.md b/solution/2400-2499/2430.Maximum Deletions on a String/README_EN.md
index bd49655bb94ca..ac56f7393dd51 100644
--- a/solution/2400-2499/2430.Maximum Deletions on a String/README_EN.md
+++ b/solution/2400-2499/2430.Maximum Deletions on a String/README_EN.md
@@ -59,6 +59,29 @@ We used 4 operations so return 4. It can be proven that 4 is the maximum number
## Solutions
+**Solution 1: Memoization Search**
+
+We design a function $dfs(i)$, which represents the maximum number of operations needed to delete all characters from $s[i..]$. The answer is $dfs(0)$.
+
+The calculation process of the function $dfs(i)$ is as follows:
+
+- If $i \geq n$, then $dfs(i) = 0$, return directly.
+- Otherwise, we enumerate the length of the string $j$, where $1 \leq j \leq (n-1)/2$. If $s[i..i+j] = s[i+j..i+j+j]$, we can delete $s[i..i+j]$, then $dfs(i)=max(dfs(i), dfs(i+j)+1)$. We need to enumerate all $j$ to find the maximum value of $dfs(i)$.
+
+Here we need to quickly determine whether $s[i..i+j]$ is equal to $s[i+j..i+j+j]$. We can preprocess all the longest common prefixes of string $s$, that is, $g[i][j]$ represents the length of the longest common prefix of $s[i..]$ and $s[j..]$. In this way, we can quickly determine whether $s[i..i+j]$ is equal to $s[i+j..i+j+j]$, that is, $g[i][i+j] \geq j$.
+
+To avoid repeated calculations, we can use memoization search and use an array $f$ to record the value of the function $dfs(i)$.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string $s$.
+
+**Solution 2: Dynamic Programming**
+
+We can change the memoization search in Solution 1 to dynamic programming. Define $f[i]$ to represent the maximum number of operations needed to delete all characters from $s[i..]$. Initially, $f[i]=1$, and the answer is $f[0]$.
+
+We can enumerate $i$ from back to front. For each $i$, we enumerate the length of the string $j$, where $1 \leq j \leq (n-1)/2$. If $s[i..i+j] = s[i+j..i+j+j]$, we can delete $s[i..i+j]$, then $f[i]=max(f[i], f[i+j]+1)$. We need to enumerate all $j$ to find the maximum value of $f[i]$.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$.
+
### **Python3**
diff --git a/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README.md b/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README.md
index dd83245c179e0..18a1388441913 100644
--- a/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README.md
+++ b/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README.md
@@ -73,7 +73,7 @@
**方法一:记忆化搜索**
-设计函数 $dfs(i, j, k)$ 表示从第 $i$ 个水果开始,剩余 $j$ 元钱,剩余 $k$ 张优惠券时,最大的总美味度。
+我们设计函数 $dfs(i, j, k)$ 表示从第 $i$ 个水果开始,剩余 $j$ 元钱,剩余 $k$ 张优惠券时,最大的总美味度。
对于第 $i$ 个水果,可以选择购买或者不购买,如果购买,那么可以选择使用优惠券或者不使用优惠券。
diff --git a/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README_EN.md b/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README_EN.md
index 92858a7a74984..e5c765b4bc7b2 100644
--- a/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README_EN.md
+++ b/solution/2400-2499/2431.Maximize Total Tastiness of Purchased Fruits/README_EN.md
@@ -63,6 +63,20 @@ It can be proven that 28 is the maximum total tastiness that can be obtained.
## Solutions
+**Solution 1: Memoization Search**
+
+We design a function $dfs(i, j, k)$ to represent the maximum total tastiness starting from the $i$th fruit, with $j$ money left, and $k$ coupons left.
+
+For the $i$th fruit, we can choose to buy or not to buy. If we choose to buy, we can decide whether to use a coupon or not.
+
+If we don't buy, the maximum total tastiness is $dfs(i + 1, j, k)$;
+
+If we buy, and choose not to use a coupon (requires $j\ge price[i]$), the maximum total tastiness is $dfs(i + 1, j - price[i], k) + tastiness[i]$; if we use a coupon (requires $k\gt 0$ and $j\ge \lfloor \frac{price[i]}{2} \rfloor$), the maximum total tastiness is $dfs(i + 1, j - \lfloor \frac{price[i]}{2} \rfloor, k - 1) + tastiness[i]$.
+
+The final answer is $dfs(0, maxAmount, maxCoupons)$.
+
+The time complexity is $O(n \times maxAmount \times maxCoupons)$, where $n$ is the number of fruits.
+
### **Python3**
diff --git a/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README.md b/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README.md
index 72fd6cb483c18..af98b530929a4 100644
--- a/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README.md
+++ b/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README.md
@@ -84,7 +84,7 @@
最后返回答案 $ans$ 即可。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $logs$ 的长度。
+时间复杂度 $O(n)$,其中 $n$ 为数组 $logs$ 的长度。空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README_EN.md b/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README_EN.md
index addc0f1e582cc..333e40976371a 100644
--- a/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README_EN.md
+++ b/solution/2400-2499/2432.The Employee That Worked on the Longest Task/README_EN.md
@@ -70,6 +70,16 @@ The tasks with the longest time are tasks 0 and 1. The employees that worked on
## Solutions
+**Solution 1: Direct Traversal**
+
+We use a variable $last$ to record the end time of the last task, a variable $mx$ to record the longest working time, and a variable $ans$ to record the employee with the longest working time and the smallest $id$. Initially, all three variables are $0$.
+
+Next, we traverse the array $logs$. For each employee, we subtract the end time of the last task from the time the employee completes the task to get the working time $t$ of this employee. If $mx$ is less than $t$, or $mx$ equals $t$ and the $id$ of this employee is less than $ans$, then we update $mx$ and $ans$. Then we update $last$ to be the end time of the last task plus $t$. Continue to traverse until the entire array is traversed.
+
+Finally, return the answer $ans$.
+
+The time complexity is $O(n)$, where $n$ is the length of the array $logs$. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README.md b/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README.md
index cb8b3845d47ff..7b9dd52f13a93 100644
--- a/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README.md
+++ b/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README.md
@@ -72,7 +72,7 @@ $$
即答案数组的每一项都是前缀异或数组的相邻两项进行异或运算得到的。
-时间复杂度 $O(n)$,忽略答案的空间消耗,空间复杂度 $O(1)$。其中 $n$ 为前缀异或数组的长度。
+时间复杂度 $O(n)$,其中 $n$ 为前缀异或数组的长度。忽略答案的空间消耗,空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README_EN.md b/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README_EN.md
index 0ca4f5a85c02e..719f5ea0e5205 100644
--- a/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README_EN.md
+++ b/solution/2400-2499/2433.Find The Original Array of Prefix Xor/README_EN.md
@@ -46,6 +46,30 @@
## Solutions
+**Solution 1: Bit Manipulation**
+
+According to the problem statement, we have equation one:
+
+$$
+pref[i]=arr[0] \oplus arr[1] \oplus \cdots \oplus arr[i]
+$$
+
+So, we also have equation two:
+
+$$
+pref[i-1]=arr[0] \oplus arr[1] \oplus \cdots \oplus arr[i-1]
+$$
+
+We perform a bitwise XOR operation on equations one and two, and get:
+
+$$
+pref[i] \oplus pref[i-1]=arr[i]
+$$
+
+That is, each item in the answer array is obtained by performing a bitwise XOR operation on the adjacent two items in the prefix XOR array.
+
+The time complexity is $O(n)$, where $n$ is the length of the prefix XOR array. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2434.Using a Robot to Print the Lexicographically Smallest String/README_EN.md b/solution/2400-2499/2434.Using a Robot to Print the Lexicographically Smallest String/README_EN.md
index 4a8b99e698e17..ce987506c168a 100644
--- a/solution/2400-2499/2434.Using a Robot to Print the Lexicographically Smallest String/README_EN.md
+++ b/solution/2400-2499/2434.Using a Robot to Print the Lexicographically Smallest String/README_EN.md
@@ -58,6 +58,18 @@ Perform second operation four times p="addb", s="", t="
## Solutions
+**Solution 1: Greedy + Stack**
+
+The problem can be transformed into, given a string sequence, convert it into the lexicographically smallest string sequence with the help of an auxiliary stack.
+
+We can use an array `cnt` to maintain the occurrence count of each character in string $s$, use a stack `stk` as the auxiliary stack in the problem, and use a variable `mi` to maintain the smallest character in the string that has not been traversed yet.
+
+Traverse the string $s$, for each character $c$, we first decrement the occurrence count of character $c$ in array `cnt`, and update `mi`. Then push character $c$ into the stack. At this point, if the top element of the stack is less than or equal to `mi`, then loop to pop the top element of the stack, and add the popped character to the answer.
+
+After the traversal ends, return the answer.
+
+The time complexity is $O(n+C)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$, and $C$ is the size of the character set, in this problem $C=26$.
+
### **Python3**
diff --git a/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README.md b/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README.md
index 38216e92024a6..8143539811afe 100644
--- a/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README.md
+++ b/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README.md
@@ -66,7 +66,7 @@ $$
答案为 `dfs(0, 0, 0)`。记忆化搜索即可。
-时间复杂度 $O(m\times n\times k)$,空间复杂度 $O(m\times n\times k)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数,而 $k$ 为给定的整数。
+时间复杂度 $O(m \times n \times k)$,空间复杂度 $O(m \times n \times k)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数,而 $k$ 为给定的整数。
**方法二:动态规划**
@@ -82,7 +82,7 @@ $$
dp[i][j][s] = dp[i - 1][j][(s - grid[i][j])\bmod k] + dp[i][j - 1][(s - grid[i][j])\bmod k]
$$
-时间复杂度 $O(m\times n\times k)$,空间复杂度 $O(m\times n\times k)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数,而 $k$ 为给定的整数。
+时间复杂度 $O(m \times n \times k)$,空间复杂度 $O(m \times n \times k)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数,而 $k$ 为给定的整数。
diff --git a/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README_EN.md b/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README_EN.md
index 9cf7af8a210bd..53c6304b631b4 100644
--- a/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README_EN.md
+++ b/solution/2400-2499/2435.Paths in Matrix Whose Sum Is Divisible by K/README_EN.md
@@ -49,6 +49,36 @@ The second path highlighted in blue has a sum of 5 + 3 + 0 + 5 + 2 = 15 which is
## Solutions
+**Solution 1: Memoization Search**
+
+We design a function `dfs(i, j, s)` to represent the number of paths starting from `(i, j)` with an initial path sum modulo $k$ equal to $s$.
+
+For each position $(i, j)$, we can choose to move right or down, so we have:
+
+$$
+dfs(i, j, s) = dfs(i + 1, j, (s + grid[i][j]) \bmod k) + dfs(i, j + 1, (s + grid[i][j]) \bmod k)
+$$
+
+The answer is `dfs(0, 0, 0)`. We can use memoization search.
+
+The time complexity is $O(m \times n \times k)$, and the space complexity is $O(m \times n \times k)$. Here, $m$ and $n$ are the number of rows and columns of the matrix, and $k$ is the given integer.
+
+**Solution 2: Dynamic Programming**
+
+We can also use dynamic programming to solve this problem.
+
+Define the state $dp[i][j][s]$ to represent the number of paths from the starting point $(0, 0)$ to the position $(i, j)$, where the path sum modulo $k$ equals $s$.
+
+The initial value is $dp[0][0][grid[0][0] \bmod k] = 1$, and the answer is $dp[m - 1][n - 1][0]$.
+
+We can get the state transition equation:
+
+$$
+dp[i][j][s] = dp[i - 1][j][(s - grid[i][j])\bmod k] + dp[i][j - 1][(s - grid[i][j])\bmod k]
+$$
+
+The time complexity is $O(m \times n \times k)$, and the space complexity is $O(m \times n \times k)$. Here, $m$ and $n$ are the number of rows and columns of the matrix, and $k$ is the given integer.
+
### **Python3**
diff --git a/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README.md b/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README.md
index 692421f2285a6..2e3b148a5c6cc 100644
--- a/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README.md
+++ b/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README.md
@@ -68,7 +68,7 @@
接下来,我们从前往后遍历数组,维护当前子数组的最大公约数 $g$。如果当前元素 $x$ 与 $g$ 的最大公约数为 $1$,那么我们需要将当前元素作为一个新的子数组的第一个元素,因此,答案加 $1$,并将 $g$ 更新为 $x$。否则,当前元素可以与前面的元素放在同一个子数组中。继续遍历数组,直到遍历结束。
-时间复杂度 $O(n \times \log m)$,空间复杂度 $O(1)$。其中 $n$ 和 $m$ 分别是数组的长度和数组中元素的最大值。
+时间复杂度 $O(n \times \log m)$,其中 $n$ 和 $m$ 分别是数组的长度和数组中元素的最大值。空间复杂度 $O(1)$。
diff --git a/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README_EN.md b/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README_EN.md
index 2b2c56f7c25aa..a14cc8ce330f3 100644
--- a/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README_EN.md
+++ b/solution/2400-2499/2436.Minimum Split Into Subarrays With GCD Greater Than One/README_EN.md
@@ -52,6 +52,16 @@ It can be shown that splitting the array into one subarray will make the GCD = 1
## Solutions
+**Solution 1: Greedy + Mathematics**
+
+For each element in the array, if its greatest common divisor (gcd) with the previous element is $1$, then it needs to be the first element of a new subarray. Otherwise, it can be placed in the same subarray with the previous elements.
+
+Therefore, we first initialize a variable $g$, representing the gcd of the current subarray. Initially, $g=0$ and the answer variable $ans=1$.
+
+Next, we traverse the array from front to back, maintaining the gcd $g$ of the current subarray. If the gcd of the current element $x$ and $g$ is $1$, then we need to make the current element the first element of a new subarray. Therefore, the answer increases by $1$, and $g$ is updated to $x$. Otherwise, the current element can be placed in the same subarray with the previous elements. Continue to traverse the array until the traversal ends.
+
+The time complexity is $O(n \times \log m)$, where $n$ and $m$ are the length of the array and the maximum value in the array, respectively. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2437.Number of Valid Clock Times/README_EN.md b/solution/2400-2499/2437.Number of Valid Clock Times/README_EN.md
index df8943cab06d9..a5c2bf15d03ed 100644
--- a/solution/2400-2499/2437.Number of Valid Clock Times/README_EN.md
+++ b/solution/2400-2499/2437.Number of Valid Clock Times/README_EN.md
@@ -47,6 +47,20 @@
## Solutions
+**Solution 1: Enumeration**
+
+We can directly enumerate all times from $00:00$ to $23:59$, then judge whether each time is valid, if so, increment the answer.
+
+After the enumeration ends, return the answer.
+
+The time complexity is $O(24 \times 60)$, and the space complexity is $O(1)$.
+
+**Solution 2: Optimized Enumeration**
+
+We can separately enumerate hours and minutes, count how many hours and minutes meet the condition, and then multiply them together.
+
+The time complexity is $O(24 + 60)$, and the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2438.Range Product Queries of Powers/README.md b/solution/2400-2499/2438.Range Product Queries of Powers/README.md
index 51643d790d6fc..b4087d90cb3f0 100644
--- a/solution/2400-2499/2438.Range Product Queries of Powers/README.md
+++ b/solution/2400-2499/2438.Range Product Queries of Powers/README.md
@@ -53,7 +53,7 @@
我们先通过位运算(lowbit)得到 powers 数组,然后通过模拟的方式求出每个查询的答案。
-时间复杂度 $O(n\times \log n)$,忽略答案的空间消耗,空间复杂度 $O(\log n)$。其中 $n$ 为 $queries$ 的长度。
+时间复杂度 $O(n \times \log n)$,忽略答案的空间消耗,空间复杂度 $O(\log n)$。其中 $n$ 为 $queries$ 的长度。
diff --git a/solution/2400-2499/2438.Range Product Queries of Powers/README_EN.md b/solution/2400-2499/2438.Range Product Queries of Powers/README_EN.md
index ee2533f64c4b9..455f206fbdeab 100644
--- a/solution/2400-2499/2438.Range Product Queries of Powers/README_EN.md
+++ b/solution/2400-2499/2438.Range Product Queries of Powers/README_EN.md
@@ -45,6 +45,12 @@ The answer to the only query is powers[0] = 2. The answer modulo 109
## Solutions
+**Solution 1: Bit Manipulation + Simulation**
+
+First, we use bit manipulation (lowbit) to get the powers array, and then simulate to get the answer for each query.
+
+The time complexity is $O(n \times \log n)$, ignoring the space consumption of the answer, the space complexity is $O(\log n)$. Here, $n$ is the length of $queries$.
+
### **Python3**
diff --git a/solution/2400-2499/2439.Minimize Maximum of Array/README.md b/solution/2400-2499/2439.Minimize Maximum of Array/README.md
index 822fe950b236c..7ecec33d34de7 100644
--- a/solution/2400-2499/2439.Minimize Maximum of Array/README.md
+++ b/solution/2400-2499/2439.Minimize Maximum of Array/README.md
@@ -59,7 +59,7 @@ nums 中最大值为 5 。无法得到比 5 更小的最大值。
最小化数组的最大值,容易想到二分查找。我们二分枚举数组的最大值 $mx$,找到一个满足题目要求的、且值最小的 $mx$ 即可。
-时间复杂度 $O(n\times \log M)$,其中 $n$ 为数组的长度,而 $M$ 为数组中的最大值。
+时间复杂度 $O(n \times \log M)$,其中 $n$ 为数组的长度,而 $M$ 为数组中的最大值。
diff --git a/solution/2400-2499/2439.Minimize Maximum of Array/README_EN.md b/solution/2400-2499/2439.Minimize Maximum of Array/README_EN.md
index 1849e52b67f9d..37afb2216daa8 100644
--- a/solution/2400-2499/2439.Minimize Maximum of Array/README_EN.md
+++ b/solution/2400-2499/2439.Minimize Maximum of Array/README_EN.md
@@ -51,6 +51,12 @@ It is optimal to leave nums as is, and since 10 is the maximum value, we return
## Solutions
+**Solution 1: Binary Search**
+
+To minimize the maximum value of the array, it is intuitive to use binary search. We binary search for the maximum value $mx$ of the array, and find the smallest $mx$ that satisfies the problem requirements.
+
+The time complexity is $O(n \times \log M)$, where $n$ is the length of the array, and $M$ is the maximum value in the array.
+
### **Python3**
diff --git a/solution/2400-2499/2440.Create Components With Same Value/README.md b/solution/2400-2499/2440.Create Components With Same Value/README.md
index f15d21d6dbfdf..74cd6e580460e 100644
--- a/solution/2400-2499/2440.Create Components With Same Value/README.md
+++ b/solution/2400-2499/2440.Create Components With Same Value/README.md
@@ -52,15 +52,15 @@
**方法一:枚举连通块的个数**
-假设连通块的个数为 $k$,那么要删除的边数为 $k-1$,每个连通块的价值为 $\frac{s}{k}$,其中 $s$ 为 `nums` 所有节点的值之和。
+假设连通块的个数为 $k$,那么要删除的边数为 $k-1$,每个连通块的价值为 $\frac{s}{k}$,其中 $s$ 为 $nums$ 所有节点的值之和。
-我们从大到小枚举 $k$,如果存在一个 $k$,使得 $\frac{s}{k}$ 是整数,并且得到的每个连通块的价值都相等,那么直接返回 $k-1$。其中 $k$ 的初始值为 $\min(n, \frac{s}{mx})$,记 $mx$ 为 `nums` 中的最大值。
+我们从大到小枚举 $k$,如果存在一个 $k$,使得 $\frac{s}{k}$ 是整数,并且得到的每个连通块的价值都相等,那么直接返回 $k-1$。其中 $k$ 的初始值为 $\min(n, \frac{s}{mx})$,记 $mx$ 为 $nums$ 中的最大值。
关键点在于判断对于给定的 $\frac{s}{k}$,是否能划分出若干子树,使得每棵子树的价值都为 $\frac{s}{k}$。
这里我们通过 `dfs` 函数来判断,从上到下递归遍历求出各个子树的价值,如果子树价值和恰好为 $\frac{s}{k}$,说明此时划分成功,我们将价值置为 $0$ 返回给上一层,表示此子树可以与父节点断开。如果子树价值之和大于 $\frac{s}{k}$,说明此时划分失败,我们返回 $-1$,表示无法划分。
-时间复杂度 $O(n\times \sqrt{s})$,其中 $n$ 和 $s$ 分别为 `nums` 的长度和 `nums` 所有节点的值之和。
+时间复杂度 $O(n \times \sqrt{s})$,其中 $n$ 和 $s$ 分别为 $nums$ 的长度和 $nums$ 所有节点的值之和。
diff --git a/solution/2400-2499/2440.Create Components With Same Value/README_EN.md b/solution/2400-2499/2440.Create Components With Same Value/README_EN.md
index d4065fabdf6e8..2425cd5861c1b 100644
--- a/solution/2400-2499/2440.Create Components With Same Value/README_EN.md
+++ b/solution/2400-2499/2440.Create Components With Same Value/README_EN.md
@@ -44,6 +44,18 @@
## Solutions
+**Solution 1: Enumeration of Connected Blocks**
+
+Assume the number of connected blocks is $k$, then the number of edges to be deleted is $k-1$, and the value of each connected block is $\frac{s}{k}$, where $s$ is the sum of the values of all nodes in $nums$.
+
+We enumerate $k$ from large to small. If there exists a $k$ such that $\frac{s}{k}$ is an integer, and the value of each connected block obtained is equal, then directly return $k-1$. The initial value of $k$ is $\min(n, \frac{s}{mx})$, where $mx$ is the maximum value in $nums$.
+
+The key point is to judge whether for a given $\frac{s}{k}$, it is possible to divide several subtrees such that the value of each subtree is $\frac{s}{k}$.
+
+Here we use the `dfs` function to judge. We recursively traverse from top to bottom to calculate the value of each subtree. If the sum of the subtree values is exactly $\frac{s}{k}$, it means that the division is successful at this time. We set the value to $0$ and return it to the upper level, indicating that this subtree can be disconnected from the parent node. If the sum of the subtree values is greater than $\frac{s}{k}$, it means that the division fails at this time. We return $-1$, indicating that it cannot be divided.
+
+The time complexity is $O(n \times \sqrt{s})$, where $n$ and $s$ are the length of $nums$ and the sum of the values of all nodes in $nums$, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2441.Largest Positive Integer That Exists With Its Negative/README_EN.md b/solution/2400-2499/2441.Largest Positive Integer That Exists With Its Negative/README_EN.md
index 9e1ae3a7d6021..a1e304428ad41 100644
--- a/solution/2400-2499/2441.Largest Positive Integer That Exists With Its Negative/README_EN.md
+++ b/solution/2400-2499/2441.Largest Positive Integer That Exists With Its Negative/README_EN.md
@@ -44,6 +44,16 @@
## Solutions
+**Solution 1: Hash Table**
+
+We can use a hash table $s$ to record all elements that appear in the array, and a variable $ans$ to record the maximum positive integer that satisfies the problem requirements, initially $ans = -1$.
+
+Next, we traverse each element $x$ in the hash table $s$. If $-x$ exists in $s$, then we update $ans = \max(ans, x)$.
+
+After the traversal ends, return $ans$.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2442.Count Number of Distinct Integers After Reverse Operations/README_EN.md b/solution/2400-2499/2442.Count Number of Distinct Integers After Reverse Operations/README_EN.md
index b49cffcc9f12b..40aee5d494e78 100644
--- a/solution/2400-2499/2442.Count Number of Distinct Integers After Reverse Operations/README_EN.md
+++ b/solution/2400-2499/2442.Count Number of Distinct Integers After Reverse Operations/README_EN.md
@@ -39,6 +39,12 @@ The number of distinct integers in this array is 1 (The number 2).
## Solutions
+**Solution 1: Hash Table**
+
+First, we use a hash table to record all integers in the array. Then, we traverse each integer in the array, reverse it, and add the reversed integer to the hash table. Finally, we return the size of the hash table.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2443.Sum of Number and Its Reverse/README.md b/solution/2400-2499/2443.Sum of Number and Its Reverse/README.md
index 3e7b0e9599630..b85cae1e6446d 100644
--- a/solution/2400-2499/2443.Sum of Number and Its Reverse/README.md
+++ b/solution/2400-2499/2443.Sum of Number and Its Reverse/README.md
@@ -52,7 +52,7 @@
在 $[0,.., num]$ 范围内枚举 $k$,判断 $k + reverse(k)$ 是否等于 $num$ 即可。
-时间复杂度 $O(n\times \log n)。其中 $n$ 为 `num` 的大小。
+时间复杂度 $O(n \times \log n)。其中 $n$ 为 $num$ 的大小。
diff --git a/solution/2400-2499/2443.Sum of Number and Its Reverse/README_EN.md b/solution/2400-2499/2443.Sum of Number and Its Reverse/README_EN.md
index 6975e4a2b9c73..a77d441fa271c 100644
--- a/solution/2400-2499/2443.Sum of Number and Its Reverse/README_EN.md
+++ b/solution/2400-2499/2443.Sum of Number and Its Reverse/README_EN.md
@@ -40,6 +40,12 @@
## Solutions
+**Solution 1: Brute Force Enumeration**
+
+Enumerate $k$ in the range $[0,.., num]$, and check whether $k + reverse(k)$ equals $num$.
+
+The time complexity is $O(n \times \log n)$, where $n$ is the size of $num$.
+
### **Python3**
diff --git a/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README.md b/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README.md
index 3a6155ffc0be2..45bce7ce150a5 100644
--- a/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README.md
+++ b/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README.md
@@ -51,7 +51,7 @@
由题意,我们可以知道,定界子数组的所有元素都在区间 `[minK, maxK]` 中,且最小值一定为 `minK`,最大值一定为 `maxK`。
-我们遍历数组 `nums`,统计以 `nums[i]` 为右端点的定界子数组的个数,然后将所有的个数相加即可。
+我们遍历数组 $nums$,统计以 `nums[i]` 为右端点的定界子数组的个数,然后将所有的个数相加即可。
具体实现逻辑如下:
@@ -59,7 +59,7 @@
1. 维护最近一个值为 `minK` 的下标 $j_1$,最近一个值为 `maxK` 的下标 $j_2$,初始值均为 $-1$。那么当前元素 `nums[i]` 的左端点一定小于等于 $\min(j_1, j_2)$。
1. 综上可知,以当前元素为右端点的定界子数组的个数为 $\max(0, \min(j_1, j_2) - k)$。累加所有的个数即可。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `nums` 的长度。
+时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $nums$ 的长度。
diff --git a/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README_EN.md b/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README_EN.md
index 3297a845e4a65..28931d0d3cf15 100644
--- a/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README_EN.md
+++ b/solution/2400-2499/2444.Count Subarrays With Fixed Bounds/README_EN.md
@@ -44,6 +44,20 @@
## Solutions
+**Solution 1: Enumeration of Right Endpoint**
+
+From the problem description, we know that all elements of the bounded subarray are in the interval `[minK, maxK]`, and the minimum value must be `minK`, and the maximum value must be `maxK`.
+
+We traverse the array $nums$, count the number of bounded subarrays with `nums[i]` as the right endpoint, and then add all the counts.
+
+The specific implementation logic is as follows:
+
+1. Maintain the index $k$ of the most recent element not in the interval `[minK, maxK]`, initially set to $-1$. Therefore, the left endpoint of the current element `nums[i]` must be greater than $k$.
+1. Maintain the index $j_1$ of the most recent element with a value of `minK`, and the index $j_2$ of the most recent element with a value of `maxK`, both initially set to $-1$. Therefore, the left endpoint of the current element `nums[i]` must be less than or equal to $\min(j_1, j_2)$.
+1. In summary, the number of bounded subarrays with the current element as the right endpoint is $\max(0, \min(j_1, j_2) - k)$. Add up all the counts to get the result.
+
+The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2445.Number of Nodes With Value One/README.md b/solution/2400-2499/2445.Number of Nodes With Value One/README.md
index 074527e26af10..fec02733f5ce2 100644
--- a/solution/2400-2499/2445.Number of Nodes With Value One/README.md
+++ b/solution/2400-2499/2445.Number of Nodes With Value One/README.md
@@ -63,7 +63,7 @@
这里有一个优化点,每个节点及其对应的子树,如果经过了偶数次查询,那么节点值不会发生变化,因此我们可以记录每个节点的查询次数,对于奇数次查询的节点及其子树,才进行反转。
-时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。其中 $n$ 为节点个数。
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为节点个数。
diff --git a/solution/2400-2499/2445.Number of Nodes With Value One/README_EN.md b/solution/2400-2499/2445.Number of Nodes With Value One/README_EN.md
index 3e603155b15d6..4e7cab896bd0c 100644
--- a/solution/2400-2499/2445.Number of Nodes With Value One/README_EN.md
+++ b/solution/2400-2499/2445.Number of Nodes With Value One/README_EN.md
@@ -51,6 +51,14 @@ After processing the queries, there are one red node (node with value 1): 2.
## Solutions
+**Solution 1: Simulation**
+
+According to the problem description, we can simulate the process of each query, that is, reverse the values of the query node and its subtree nodes. Finally, count the number of nodes with a value of 1.
+
+There is an optimization point here. If a node and its corresponding subtree have been queried an even number of times, the node value will not change. Therefore, we can record the number of queries for each node, and only reverse the nodes and their subtrees that have been queried an odd number of times.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes.
+
### **Python3**
diff --git a/solution/2400-2499/2446.Determine if Two Events Have Conflict/README_EN.md b/solution/2400-2499/2446.Determine if Two Events Have Conflict/README_EN.md
index 355dcb69976fe..873ef668d007b 100644
--- a/solution/2400-2499/2446.Determine if Two Events Have Conflict/README_EN.md
+++ b/solution/2400-2499/2446.Determine if Two Events Have Conflict/README_EN.md
@@ -55,6 +55,14 @@
## Solutions
+**Solution 1: String Comparison**
+
+If the start time of $event1$ is later than the end time of $event2$, or the end time of $event1$ is earlier than the start time of $event2$, then the two events will not conflict. Otherwise, the two events will conflict.
+
+
+
+The time complexity is $O(1)$, and the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README.md b/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README.md
index 47eac80215206..7dbf4c754bdb5 100644
--- a/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README.md
+++ b/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README.md
@@ -47,11 +47,11 @@
**方法一:直接枚举**
-我们可以枚举 $nums[i]$ 作为子数组的左端点,然后枚举 $nums[j]$ 作为子数组的右端点,其中 $i\le j$。在枚举右端点的过程中,我们可以用一个变量 $g$ 来维护当前子数组的最大公因数,每次枚举到一个新的右端点时,我们更新最大公因数 $g = \gcd(g, nums[j])$。如果 $g=k$,那么当前子数组的最大公因数等于 $k$,我们就将答案增加 $1$。
+我们可以枚举 $nums[i]$ 作为子数组的左端点,然后枚举 $nums[j]$ 作为子数组的右端点,其中 $i \le j$。在枚举右端点的过程中,我们可以用一个变量 $g$ 来维护当前子数组的最大公因数,每次枚举到一个新的右端点时,我们更新最大公因数 $g = \gcd(g, nums[j])$。如果 $g=k$,那么当前子数组的最大公因数等于 $k$,我们就将答案增加 $1$。
枚举结束后,返回答案即可。
-时间复杂度 $O(n \times (n + \log M))$,其中 $n$ 和 $M$ 分别是数组 `nums` 的长度和数组 `nums` 中的最大值。
+时间复杂度 $O(n \times (n + \log M))$,其中 $n$ 和 $M$ 分别是数组 $nums$ 的长度和数组 $nums$ 中的最大值。
diff --git a/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README_EN.md b/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README_EN.md
index a2209f8ac1108..304fb2e61e042 100644
--- a/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README_EN.md
+++ b/solution/2400-2499/2447.Number of Subarrays With GCD Equal to K/README_EN.md
@@ -41,6 +41,14 @@
## Solutions
+**Solution 1: Direct Enumeration**
+
+We can enumerate $nums[i]$ as the left endpoint of the subarray, and then enumerate $nums[j]$ as the right endpoint of the subarray, where $i \le j$. During the enumeration of the right endpoint, we can use a variable $g$ to maintain the greatest common divisor of the current subarray. Each time we enumerate a new right endpoint, we update the greatest common divisor $g = \gcd(g, nums[j])$. If $g=k$, then the greatest common divisor of the current subarray equals $k$, and we increase the answer by $1$.
+
+After the enumeration ends, return the answer.
+
+The time complexity is $O(n \times (n + \log M))$, where $n$ and $M$ are the length of the array $nums$ and the maximum value in the array $nums$, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2448.Minimum Cost to Make Array Equal/README_EN.md b/solution/2400-2499/2448.Minimum Cost to Make Array Equal/README_EN.md
index 731f4cafc2410..4af10d4e39894 100644
--- a/solution/2400-2499/2448.Minimum Cost to Make Array Equal/README_EN.md
+++ b/solution/2400-2499/2448.Minimum Cost to Make Array Equal/README_EN.md
@@ -50,6 +50,38 @@ It can be shown that we cannot make the array equal with a smaller cost.
## Solutions
+**Solution 1: Prefix Sum + Sorting + Enumeration**
+
+Let's denote the elements of the array `nums` as $a_1, a_2, \cdots, a_n$ and the elements of the array `cost` as $b_1, b_2, \cdots, b_n$. We can assume that $a_1 \leq a_2 \leq \cdots \leq a_n$, i.e., the array `nums` is sorted in ascending order.
+
+Suppose we change all elements in the array `nums` to $x$, then the total cost we need is:
+
+$$
+\begin{aligned}
+\sum_{i=1}^{n} \left | a_i-x \right | b_i &= \sum_{i=1}^{k} (x-a_i)b_i + \sum_{i=k+1}^{n} (a_i-x)b_i \\
+&= x\sum_{i=1}^{k} b_i - \sum_{i=1}^{k} a_ib_i + \sum_{i=k+1}^{n}a_ib_i - x\sum_{i=k+1}^{n}b_i
+\end{aligned}
+$$
+
+where $k$ is the number of elements in $a_1, a_2, \cdots, a_n$ that are less than or equal to $x$.
+
+We can use the prefix sum method to calculate $\sum_{i=1}^{k} b_i$ and $\sum_{i=1}^{k} a_ib_i$, as well as $\sum_{i=k+1}^{n}a_ib_i$ and $\sum_{i=k+1}^{n}b_i$.
+
+Then we enumerate $x$, calculate the above four prefix sums, get the total cost mentioned above, and take the minimum value.
+
+The time complexity is $O(n\times \log n)$, where $n$ is the length of the array `nums`. The main time complexity comes from sorting.
+
+**Solution 2: Sorting + Median**
+
+We can also consider $b_i$ as the occurrence times of $a_i$, then the index of the median is $\frac{\sum_{i=1}^{n} b_i}{2}$. Changing all numbers to the median is definitely optimal.
+
+The time complexity is $O(n\times \log n)$, where $n$ is the length of the array `nums`. The main time complexity comes from sorting.
+
+Similar problems:
+
+- [296. Best Meeting Point](/solution/0200-0299/0296.Best%20Meeting%20Point/README_EN.md)
+- [462. Minimum Moves to Equal Array Elements II](/solution/0400-0499/0462.Minimum%20Moves%20to%20Equal%20Array%20Elements%20II/README_EN.md)
+
### **Python3**
diff --git a/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README.md b/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README.md
index bab7c253234eb..8ef7d4eca048d 100644
--- a/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README.md
+++ b/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README.md
@@ -68,13 +68,13 @@
注意到,由于每次操作,元素的值只会增加 $2$ 或减少 $2$,因此,元素的奇偶性不会改变。
-因此,我们可以将数组 `nums` 和 `target` 分别按奇偶性分为两组,分别记为 $a_1$ 和 $a_2$,以及 $b_1$ 和 $b_2$。
+因此,我们可以将数组 $nums$ 和 $target$ 分别按奇偶性分为两组,分别记为 $a_1$ 和 $a_2$,以及 $b_1$ 和 $b_2$。
那么,我们只需要将 $a_1$ 中的元素与 $b_1$ 中的元素配对,将 $a_2$ 中的元素与 $b_2$ 中的元素配对,然后进行操作。配对的过程中,我们可以使用贪心的策略,每次将 $a_i$ 中较小的元素与 $b_i$ 中较小的元素配对,这样可以保证操作的次数最少。这里可以直接通过排序来实现。
由于每次操作,都可以将对应位置的元素差值减少 $4$,因此,我们累计每个对应位置的差值,最后除以 $4$ 即可得到答案。
-时间复杂度 $O(n\times \log n)$,其中 $n$ 为数组 `nums` 的长度。
+时间复杂度 $O(n \times \log n)$,其中 $n$ 为数组 $nums$ 的长度。
diff --git a/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README_EN.md b/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README_EN.md
index d16255c92f1bc..79935dbe74119 100644
--- a/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README_EN.md
+++ b/solution/2400-2499/2449.Minimum Number of Operations to Make Arrays Similar/README_EN.md
@@ -58,6 +58,18 @@ It can be shown that 2 is the minimum number of operations needed.
## Solutions
+**Solution 1: Odd-Even Classification + Sorting**
+
+Notice that, because each operation will only increase or decrease the value of an element by $2$, the parity of the element will not change.
+
+Therefore, we can divide the arrays $nums$ and $target$ into two groups according to their parity, denoted as $a_1$ and $a_2$, and $b_1$ and $b_2$ respectively.
+
+Then, we just need to pair the elements in $a_1$ with the elements in $b_1$, and pair the elements in $a_2$ with the elements in $b_2$, and then perform operations. During the pairing process, we can use a greedy strategy, pairing the smaller elements in $a_i$ with the smaller elements in $b_i$ each time, which can ensure the minimum number of operations. This can be directly implemented through sorting.
+
+Since each operation can reduce the difference of the corresponding elements by $4$, we accumulate the difference of each corresponding position, and finally divide by $4$ to get the answer.
+
+The time complexity is $O(n \times \log n)$, where $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2450.Number of Distinct Binary Strings After Applying Operations/README_EN.md b/solution/2400-2499/2450.Number of Distinct Binary Strings After Applying Operations/README_EN.md
index 2b70bf8fc131c..13799228389c2 100644
--- a/solution/2400-2499/2450.Number of Distinct Binary Strings After Applying Operations/README_EN.md
+++ b/solution/2400-2499/2450.Number of Distinct Binary Strings After Applying Operations/README_EN.md
@@ -55,6 +55,12 @@ It can be shown that we cannot obtain any other string, so the answer is 2.
## Solutions
+**Solution 1: Mathematics**
+
+Assume the length of the string $s$ is $n$. Then there are $n - k + 1$ substrings of length $k$, and each substring can be flipped, so there are $2^{n - k + 1}$ ways to flip.
+
+The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the string $s$.
+
### **Python3**
diff --git a/solution/2400-2499/2451.Odd String Difference/README_EN.md b/solution/2400-2499/2451.Odd String Difference/README_EN.md
index 3417e1f63a03b..e46922b8607f9 100644
--- a/solution/2400-2499/2451.Odd String Difference/README_EN.md
+++ b/solution/2400-2499/2451.Odd String Difference/README_EN.md
@@ -49,6 +49,12 @@ The odd array out is [1, 1], so we return the corresponding string, "abc&qu
## Solutions
+**Solution 1: Hash Table Simulation**
+
+We use a hash table $d$ to maintain the mapping relationship between the difference array of the string and the string itself, where the difference array is an array composed of the differences of adjacent characters in the string. Since the problem guarantees that except for one string, the difference arrays of other strings are the same, we only need to find the string with a different difference array.
+
+The time complexity is $O(m \times n)$, and the space complexity is $O(m + n)$. Here, $m$ and $n$ are the length of the string and the number of strings, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2453.Destroy Sequential Targets/README.md b/solution/2400-2499/2453.Destroy Sequential Targets/README.md
index bbcd57bef47ee..58f4d6d978ce9 100644
--- a/solution/2400-2499/2453.Destroy Sequential Targets/README.md
+++ b/solution/2400-2499/2453.Destroy Sequential Targets/README.md
@@ -55,9 +55,9 @@
**方法一:取模 + 枚举**
-我们遍历数组 `nums`,用哈希表 `cnt` 统计每个数模 `space` 后的余数出现的次数。次数越多,意味着可以摧毁的目标越多。我们找到最多次数的组,取组中的最小值即可。
+我们遍历数组 $nums$,用哈希表 $cnt$ 统计每个数模 $space$ 后的余数出现的次数。次数越多,意味着可以摧毁的目标越多。我们找到最多次数的组,取组中的最小值即可。
-时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
diff --git a/solution/2400-2499/2453.Destroy Sequential Targets/README_EN.md b/solution/2400-2499/2453.Destroy Sequential Targets/README_EN.md
index 27165a803a82c..083475441d08c 100644
--- a/solution/2400-2499/2453.Destroy Sequential Targets/README_EN.md
+++ b/solution/2400-2499/2453.Destroy Sequential Targets/README_EN.md
@@ -50,6 +50,12 @@ Since nums[0] is the minimal integer that can destroy 3 targets, we return 1.
## Solutions
+**Solution 1: Modulo + Enumeration**
+
+We traverse the array $nums$ and use a hash table $cnt$ to count the frequency of each number modulo $space$. The higher the frequency, the more targets can be destroyed. We find the group with the highest frequency and take the minimum value in the group.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2454.Next Greater Element IV/README.md b/solution/2400-2499/2454.Next Greater Element IV/README.md
index caf0a7a09dfd8..b2da97d8a8cb1 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/README.md
+++ b/solution/2400-2499/2454.Next Greater Element IV/README.md
@@ -109,7 +109,7 @@ class Solution {
for (int i = 0; i < n; ++i) {
arr[i] = new int[] {nums[i], i};
}
- Arrays.sort(arr, (a, b) -> b[0] - a[0]);
+ Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]);
TreeSet ts = new TreeSet<>();
for (int[] pair : arr) {
int i = pair[1];
@@ -159,7 +159,7 @@ function secondGreaterElement(nums: number[]): number[] {
for (let i = 0; i < n; ++i) {
arr.push([nums[i], i]);
}
- arr.sort((a, b) => b[0] - a[0]);
+ arr.sort((a, b) => (a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]));
const ans = Array(n).fill(-1);
const ts = new TreeSet();
for (const [_, i] of arr) {
diff --git a/solution/2400-2499/2454.Next Greater Element IV/README_EN.md b/solution/2400-2499/2454.Next Greater Element IV/README_EN.md
index 5fcd54968e6be..1d9c3fb1d899f 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/README_EN.md
+++ b/solution/2400-2499/2454.Next Greater Element IV/README_EN.md
@@ -99,7 +99,7 @@ class Solution {
for (int i = 0; i < n; ++i) {
arr[i] = new int[] {nums[i], i};
}
- Arrays.sort(arr, (a, b) -> b[0] - a[0]);
+ Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]);
TreeSet ts = new TreeSet<>();
for (int[] pair : arr) {
int i = pair[1];
@@ -149,7 +149,7 @@ function secondGreaterElement(nums: number[]): number[] {
for (let i = 0; i < n; ++i) {
arr.push([nums[i], i]);
}
- arr.sort((a, b) => b[0] - a[0]);
+ arr.sort((a, b) => (a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]));
const ans = Array(n).fill(-1);
const ts = new TreeSet();
for (const [_, i] of arr) {
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.java b/solution/2400-2499/2454.Next Greater Element IV/Solution.java
index fcfa3bdb6ef18..df8365bb3bab1 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/Solution.java
+++ b/solution/2400-2499/2454.Next Greater Element IV/Solution.java
@@ -7,7 +7,7 @@ public int[] secondGreaterElement(int[] nums) {
for (int i = 0; i < n; ++i) {
arr[i] = new int[] {nums[i], i};
}
- Arrays.sort(arr, (a, b) -> b[0] - a[0]);
+ Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]);
TreeSet ts = new TreeSet<>();
for (int[] pair : arr) {
int i = pair[1];
diff --git a/solution/2400-2499/2454.Next Greater Element IV/Solution.ts b/solution/2400-2499/2454.Next Greater Element IV/Solution.ts
index ca95a6a4e7bcf..fdb1042e3feea 100644
--- a/solution/2400-2499/2454.Next Greater Element IV/Solution.ts
+++ b/solution/2400-2499/2454.Next Greater Element IV/Solution.ts
@@ -4,7 +4,7 @@ function secondGreaterElement(nums: number[]): number[] {
for (let i = 0; i < n; ++i) {
arr.push([nums[i], i]);
}
- arr.sort((a, b) => b[0] - a[0]);
+ arr.sort((a, b) => (a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]));
const ans = Array(n).fill(-1);
const ts = new TreeSet();
for (const [_, i] of arr) {
diff --git a/solution/2400-2499/2455.Average Value of Even Numbers That Are Divisible by Three/README_EN.md b/solution/2400-2499/2455.Average Value of Even Numbers That Are Divisible by Three/README_EN.md
index f91e21b95e028..73731a3e5393a 100644
--- a/solution/2400-2499/2455.Average Value of Even Numbers That Are Divisible by Three/README_EN.md
+++ b/solution/2400-2499/2455.Average Value of Even Numbers That Are Divisible by Three/README_EN.md
@@ -35,6 +35,12 @@
## Solutions
+**Solution 1: Simulation**
+
+We notice that an even number divisible by $3$ must be a multiple of $6$. Therefore, we only need to traverse the array, count the sum and the number of all multiples of $6$, and then calculate the average.
+
+The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2456.Most Popular Video Creator/README_EN.md b/solution/2400-2499/2456.Most Popular Video Creator/README_EN.md
index 53f2f20ee882f..09010332771e4 100644
--- a/solution/2400-2499/2456.Most Popular Video Creator/README_EN.md
+++ b/solution/2400-2499/2456.Most Popular Video Creator/README_EN.md
@@ -53,6 +53,14 @@ Since "b" is lexicographically smaller than "c", it is inclu
## Solutions
+**Solution 1: Hash Table**
+
+We traverse the three arrays, use a hash table $cnt$ to count the total play count for each creator, and use a hash table $d$ to record the index of the video with the highest play count for each creator.
+
+Then, we traverse the hash table $cnt$ to find the maximum play count $mx$; then we traverse the hash table $cnt$ again to find the creators with a play count of $mx$, and add them to the answer array.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of videos.
+
### **Python3**
diff --git a/solution/2400-2499/2457.Minimum Addition to Make Integer Beautiful/README_EN.md b/solution/2400-2499/2457.Minimum Addition to Make Integer Beautiful/README_EN.md
index f1e2ece93018c..c579ebd323f0e 100644
--- a/solution/2400-2499/2457.Minimum Addition to Make Integer Beautiful/README_EN.md
+++ b/solution/2400-2499/2457.Minimum Addition to Make Integer Beautiful/README_EN.md
@@ -46,6 +46,27 @@
## Solutions
+**Solution 1: Greedy Algorithm**
+
+We define a function $f(x)$ to represent the sum of the digits of an integer $x$. The problem is to find the minimum non-negative integer $x$ such that $f(n + x) \leq target$.
+
+If the sum of the digits of $y = n+x$ is greater than $target$, we can loop through the following operations to reduce the sum of the digits of $y$ to less than or equal to $target$:
+
+- Find the lowest non-zero digit of $y$, reduce it to $0$, and add $1$ to the digit one place higher;
+- Update $x$ and continue the above operation until the sum of the digits of $n+x$ is less than or equal to $target$.
+
+After the loop ends, return $x$.
+
+For example, if $n=467$ and $target=6$, the change process of $n$ is as follows:
+
+$$
+\begin{aligned}
+& 467 \rightarrow 470 \rightarrow 500 \\
+\end{aligned}
+$$
+
+The time complexity is $O(\log^2 n)$, where $n$ is the integer given in the problem. The space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2458.Height of Binary Tree After Subtree Removal Queries/README_EN.md b/solution/2400-2499/2458.Height of Binary Tree After Subtree Removal Queries/README_EN.md
index fffe5365d85aa..1350ad64d1175 100644
--- a/solution/2400-2499/2458.Height of Binary Tree After Subtree Removal Queries/README_EN.md
+++ b/solution/2400-2499/2458.Height of Binary Tree After Subtree Removal Queries/README_EN.md
@@ -59,6 +59,30 @@ The height of the tree is 2 (The path 1 -> 3 -> 2).
## Solutions
+**Solution 1: Two DFS Traversals**
+
+First, we perform a DFS traversal to determine the depth of each node, which we store in a hash table $d$, where $d[x]$ represents the depth of node $x$.
+
+Then we design a function $dfs(root, depth, rest)$, where:
+
+- `root` represents the current node;
+- `depth` represents the depth of the current node;
+- `rest` represents the height of the tree after deleting the current node.
+
+The function's computation logic is as follows:
+
+If the node is null, return directly. Otherwise, we increment `depth` by $1$, and then store `rest` in `res`.
+
+Next, we recursively traverse the left and right subtrees.
+
+Before recursing into the left subtree, we calculate the depth from the root node to the deepest node in the current node's right subtree, i.e., $depth+d[root.right]$, and then compare it with `rest`, taking the larger value as the `rest` for the left subtree.
+
+Before recursing into the right subtree, we calculate the depth from the root node to the deepest node in the current node's left subtree, i.e., $depth+d[root.left]$, and then compare it with `rest`, taking the larger value as the `rest` for the right subtree.
+
+Finally, we return the result values corresponding to each query node.
+
+The time complexity is $O(n+m)$, and the space complexity is $O(n)$. Here, $n$ and $m$ are the number of nodes in the tree and the number of queries, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2459.Sort Array by Moving Items to Empty Space/README_EN.md b/solution/2400-2499/2459.Sort Array by Moving Items to Empty Space/README_EN.md
index b1816f641cb34..24d72bfdd536a 100644
--- a/solution/2400-2499/2459.Sort Array by Moving Items to Empty Space/README_EN.md
+++ b/solution/2400-2499/2459.Sort Array by Moving Items to Empty Space/README_EN.md
@@ -63,6 +63,16 @@ It can be proven that 2 is the minimum number of operations needed.
## Solutions
+**Solution 1: Permutation Cycle**
+
+For a permutation cycle of length $m$, if $0$ is in the cycle, the number of swaps is $m-1$; otherwise, the number of swaps is $m+1$.
+
+We find all permutation cycles, first calculate the total number of swaps assuming each cycle requires $m+1$ swaps, then check if $0$ is misplaced. If it is, it means $0$ is in a permutation cycle, so we subtract $2$ from the total number of swaps.
+
+Here, $0$ can be at position $0$ or at position $n-1$. We take the minimum of these two cases.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2460.Apply Operations to an Array/README_EN.md b/solution/2400-2499/2460.Apply Operations to an Array/README_EN.md
index d7800b4c2da98..8140f1655d73a 100644
--- a/solution/2400-2499/2460.Apply Operations to an Array/README_EN.md
+++ b/solution/2400-2499/2460.Apply Operations to an Array/README_EN.md
@@ -55,6 +55,18 @@ After that, we shift the 0's to the end, which gives the array [1,4,2,0,0,0]
## Solutions
+**Solution 1: Simulation**
+
+We can directly simulate according to the problem description.
+
+First, we traverse the array $nums$. For any two adjacent elements $nums[i]$ and $nums[i+1]$, if $nums[i] = nums[i+1]$, then we double the value of $nums[i]$ and change the value of $nums[i+1]$ to $0$.
+
+Then, we create an answer array $ans$ of length $n$, and put all non-zero elements of $nums$ into $ans$ in order.
+
+Finally, we return the answer array $ans$.
+
+The time complexity is $O(n)$, where $n$ is the length of the array $nums$. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2461.Maximum Sum of Distinct Subarrays With Length K/README_EN.md b/solution/2400-2499/2461.Maximum Sum of Distinct Subarrays With Length K/README_EN.md
index 8fd9122530157..1f55b2733185a 100644
--- a/solution/2400-2499/2461.Maximum Sum of Distinct Subarrays With Length K/README_EN.md
+++ b/solution/2400-2499/2461.Maximum Sum of Distinct Subarrays With Length K/README_EN.md
@@ -50,6 +50,12 @@ We return 0 because no subarrays meet the conditions.
## Solutions
+**Solution 1: Sliding Window + Hash Table**
+
+We maintain a sliding window of length $k$, use a hash table $cnt$ to record the count of each number in the window, and use a variable $s$ to record the sum of all numbers in the window. Each time we slide the window, if all numbers in the window are unique, we update the answer.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2462.Total Cost to Hire K Workers/README_EN.md b/solution/2400-2499/2462.Total Cost to Hire K Workers/README_EN.md
index ad4ae87a8aa3b..bee12e8647093 100644
--- a/solution/2400-2499/2462.Total Cost to Hire K Workers/README_EN.md
+++ b/solution/2400-2499/2462.Total Cost to Hire K Workers/README_EN.md
@@ -58,6 +58,18 @@ The total hiring cost is 4.
## Solutions
+**Solution 1: Priority Queue (Min Heap)**
+
+We maintain a priority queue (min heap) for the current candidate workers, and use variables $i$ and $j$ to mark the minimum index of the frontmost worker and the minimum index of the rearmost worker. Initially, $i = \text{candidates} - 1$ and $j = n - \text{candidates}$.
+
+First, we put the costs of the first $candidates$ workers into the priority queue, then we put the costs of the last $candidates$ workers into the priority queue. Before putting them in, we need to check whether they are already in the priority queue according to $i$ or $j$. If they are, we don't need to put them in again.
+
+We loop $k$ times, each time taking out the worker with the smallest cost from the priority queue and accumulating the cost. If the index $x$ of the current worker is in the index range $[0,..i]$ of the frontmost workers, we move $i$ one step to the right, and then check whether we need to put the cost of the worker corresponding to $i$ into the priority queue; if the index is in the index range $[j,..n-1]$ of the rearmost workers, we move $j$ one step to the left, and then check whether we need to put the cost of the worker corresponding to $j$ into the priority queue.
+
+After the traversal ends, we return the accumulated cost as the answer.
+
+The time complexity is $O(n \times \log n)$, where $n$ is the length of the array $costs$.
+
### **Python3**
diff --git a/solution/2400-2499/2463.Minimum Total Distance Traveled/README_EN.md b/solution/2400-2499/2463.Minimum Total Distance Traveled/README_EN.md
index 6f91a3c11dac1..34f599f33e938 100644
--- a/solution/2400-2499/2463.Minimum Total Distance Traveled/README_EN.md
+++ b/solution/2400-2499/2463.Minimum Total Distance Traveled/README_EN.md
@@ -65,6 +65,14 @@ The total distance is |2 - 1| + |(-2) - (-1)| = 2. It can be shown that we canno
## Solutions
+**Solution 1: Memoization Search**
+
+First, we sort the robots and factories in ascending order. Then we define a function $dfs(i, j)$ to represent the minimum total moving distance starting from the $i$-th robot and the $j$-th factory.
+
+For $dfs(i, j)$, if the $j$-th factory does not repair the robot, then $dfs(i, j) = dfs(i, j+1)$. If the $j$-th factory repairs the robot, we can enumerate the number of robots repaired by the $j$-th factory and find the minimum total moving distance. That is, $dfs(i, j) = min(dfs(i + k + 1, j + 1) + \sum_{t = 0}^{k} |robot[i + t] - factory[j][0]|)$.
+
+The time complexity is $O(m^2 \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of robots and factories, respectively.
+
### **Python3**
diff --git a/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README.md b/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README.md
index 4f434850f83eb..e4c44277555ec 100644
--- a/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README.md
+++ b/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README.md
@@ -72,7 +72,7 @@
我们设计一个函数 $dfs(i)$ 表示从下标 $i$ 开始的最小分割数。对于下标 $i$,我们可以枚举所有的分割点 $j$,即 $i \leq j \lt n$,其中 $n$ 为数组长度。对于每个分割点 $j$,我们需要判断 $nums[i]$ 和 $nums[j]$ 的最大公约数是否大于 $1$,如果大于 $1$,则可以进行分割,此时分割数为 $1 + dfs(j + 1)$,否则分割数为 $+\infty$。最后我们取所有分割数的最小值即可。
-时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。
+时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为数组长度。
diff --git a/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README_EN.md b/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README_EN.md
index 43154eccdaa88..dfe724787e4e4 100644
--- a/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README_EN.md
+++ b/solution/2400-2499/2464.Minimum Subarrays in a Valid Split/README_EN.md
@@ -63,6 +63,12 @@ It can be proved that 2 is the minimum number of subarrays that we can obtain in
## Solutions
+**Solution 1: Memoization Search**
+
+We design a function $dfs(i)$ to represent the minimum number of partitions starting from index $i$. For index $i$, we can enumerate all partition points $j$, i.e., $i \leq j < n$, where $n$ is the length of the array. For each partition point $j$, we need to determine whether the greatest common divisor of $nums[i]$ and $nums[j]$ is greater than $1$. If it is greater than $1$, we can partition, and the number of partitions is $1 + dfs(j + 1)$; otherwise, the number of partitions is $+\infty$. Finally, we take the minimum of all partition numbers.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2465.Number of Distinct Averages/README_EN.md b/solution/2400-2499/2465.Number of Distinct Averages/README_EN.md
index 4b37d4a628604..65134e6db7ac9 100644
--- a/solution/2400-2499/2465.Number of Distinct Averages/README_EN.md
+++ b/solution/2400-2499/2465.Number of Distinct Averages/README_EN.md
@@ -57,6 +57,12 @@ There is only one average to be calculated after removing 1 and 100, so we retur
## Solutions
+**Solution 1: Sorting**
+
+The problem requires us to find the minimum and maximum values in the array $nums$ each time, delete them, and then calculate the average of the two deleted numbers. Therefore, we can first sort the array $nums$, then take the first and last elements of the array each time, calculate their sum, use a hash table or array $cnt$ to record the number of times each sum appears, and finally count the number of different sums.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
+
### **Python3**
diff --git a/solution/2400-2499/2466.Count Ways To Build Good Strings/README_EN.md b/solution/2400-2499/2466.Count Ways To Build Good Strings/README_EN.md
index f5880b99573ce..acb87ce53a0aa 100644
--- a/solution/2400-2499/2466.Count Ways To Build Good Strings/README_EN.md
+++ b/solution/2400-2499/2466.Count Ways To Build Good Strings/README_EN.md
@@ -47,6 +47,19 @@ All binary strings from "000" to "111" are good strings in t
## Solutions
+**Solution 1: Memoization Search**
+
+We design a function $dfs(i)$ to represent the number of good strings constructed starting from the $i$-th position. The answer is $dfs(0)$.
+
+The computation process of the function $dfs(i)$ is as follows:
+
+- If $i > high$, return $0$;
+- If $low \leq i \leq high$, increment the answer by $1$, then after $i$, we can add either `zero` number of $0$s or `one` number of $1$s. Therefore, the answer is incremented by $dfs(i + zero) + dfs(i + one)$.
+
+During the process, we need to take the modulus of the answer, and we can use memoization search to reduce redundant computations.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n = high$.
+
### **Python3**
diff --git a/solution/2400-2499/2467.Most Profitable Path in a Tree/README_EN.md b/solution/2400-2499/2467.Most Profitable Path in a Tree/README_EN.md
index a8ba40248d0e0..8ade7690df3b1 100644
--- a/solution/2400-2499/2467.Most Profitable Path in a Tree/README_EN.md
+++ b/solution/2400-2499/2467.Most Profitable Path in a Tree/README_EN.md
@@ -76,6 +76,20 @@ Thus, Alice opens the gate at node 0 only. Hence, her net income is -7280.
## Solutions
+**Solution 1: Two DFS Traversals**
+
+According to the problem, we know that Bob's moving path is fixed, that is, starting from node $bob$ and finally reaching node $0$. Therefore, we can first run a DFS to find out the time it takes for Bob to reach each node, which we record in the array $ts$.
+
+Then we run another DFS to find the maximum score for each of Alice's moving paths. We denote the time for Alice to reach node $i$ as $t$, and the current cumulative score as $v$. After Alice passes node $i$, the cumulative score has three cases:
+
+1. The time $t$ for Alice to reach node $i$ is the same as the time $ts[i]$ for Bob to reach node $i$. In this case, Alice and Bob open the door at node $i$ at the same time, and the score Alice gets is $v + \frac{amount[i]}{2}$.
+2. The time $t$ for Alice to reach node $i$ is less than the time $ts[i]$ for Bob to reach node $i$. In this case, Alice opens the door at node $i$, and the score Alice gets is $v + amount[i]$.
+3. The time $t$ for Alice to reach node $i$ is greater than the time $ts[i]$ for Bob to reach node $i$. In this case, Alice does not open the door at node $i$, and the score Alice gets is $v$, which remains unchanged.
+
+When Alice reaches a leaf node, update the maximum score.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes.
+
### **Python3**
diff --git a/solution/2400-2499/2468.Split Message Based on Limit/README_EN.md b/solution/2400-2499/2468.Split Message Based on Limit/README_EN.md
index 71e4eff0f39ae..45cd5cbd506c3 100644
--- a/solution/2400-2499/2468.Split Message Based on Limit/README_EN.md
+++ b/solution/2400-2499/2468.Split Message Based on Limit/README_EN.md
@@ -47,6 +47,20 @@ Under the given constraints, the string can be split into two parts:
## Solutions
+**Solution 1: Enumerate the Number of Segments + Simulation**
+
+We denote the length of the string `message` as $n$, and the number of segments as $k$.
+
+According to the problem, if $k > n$, it means that we can divide the string into more than $n$ segments. Since the length of the string is only $n$, dividing it into more than $n$ segments will inevitably lead to some segments with a length of $0$, which can be deleted. Therefore, we only need to limit the range of $k$ to $[1,.. n]$.
+
+We enumerate the number of segments $k$ from small to large. Let the length of $a$ segments in all segments be $sa$, the length of $b$ segments in all segments be $sb$, and the length of all symbols (including angle brackets and slashes) in all segments be $sc$.
+
+Then the value of $sa$ is ${\textstyle \sum_{j=1}^{k}} len(s_j)$, which can be directly obtained through the prefix sum; the value of $sb$ is $len(str(k)) \times k$; and the value of $sc$ is $3 \times k$.
+
+Therefore, the number of characters that can be filled in all segments is $limit\times k - (sa + sb + sc)$. If this value is greater than or equal to $n$, it means that the string can be divided into $k$ segments, and we can directly construct the answer and return it.
+
+The time complexity is $O(n\times \log n)$, where $n$ is the length of the string `message`. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2469.Convert the Temperature/README_EN.md b/solution/2400-2499/2469.Convert the Temperature/README_EN.md
index bf666acdfa24a..0c302a40f2b4b 100644
--- a/solution/2400-2499/2469.Convert the Temperature/README_EN.md
+++ b/solution/2400-2499/2469.Convert the Temperature/README_EN.md
@@ -43,6 +43,12 @@
## Solutions
+**Solution 1: Simulation**
+
+We can directly simulate according to the problem description.
+
+The time complexity is $O(1)$, and the space complexity is $O(1)$.
+
### **Python3**
diff --git a/solution/2400-2499/2470.Number of Subarrays With LCM Equal to K/README_EN.md b/solution/2400-2499/2470.Number of Subarrays With LCM Equal to K/README_EN.md
index 6fde54dbb1ec9..39d9f75ab0c14 100644
--- a/solution/2400-2499/2470.Number of Subarrays With LCM Equal to K/README_EN.md
+++ b/solution/2400-2499/2470.Number of Subarrays With LCM Equal to K/README_EN.md
@@ -41,6 +41,12 @@
## Solutions
+**Solution 1: Enumeration**
+
+Enumerate each number as the first number of the subarray, and then enumerate each number as the last number of the subarray. Calculate the least common multiple of this subarray. If the least common multiple equals $k$, then increment the answer by one.
+
+The time complexity is $O(n^2)$. Here, $n$ is the length of the array.
+
### **Python3**
diff --git a/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README.md b/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README.md
index b9bb5dbefbddf..fd9449671fd9e 100644
--- a/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README.md
+++ b/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README.md
@@ -65,7 +65,7 @@
我们先通过 `BFS` 遍历二叉树,找到每一层的节点值,然后对每一层的节点值进行排序,如果排序后的节点值与原节点值不同,则说明需要交换元素,交换元素的次数即为该层需要的操作数。
-时间复杂度 $O(n\times \log n)$。其中 $n$ 为二叉树的节点数。
+时间复杂度 $O(n \times \log n)$。其中 $n$ 为二叉树的节点数。
diff --git a/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README_EN.md b/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README_EN.md
index 32dfcff6655a5..7cdbb239506f3 100644
--- a/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README_EN.md
+++ b/solution/2400-2499/2471.Minimum Number of Operations to Sort a Binary Tree by Level/README_EN.md
@@ -58,6 +58,12 @@ It can be proven that 3 is the minimum number of operations needed.
## Solutions
+**Solution 1: BFS + Discretization + Element Swap**
+
+First, we traverse the binary tree using BFS to find the node values at each level. Then, we sort the node values at each level. If the sorted node values are different from the original node values, it means that we need to swap elements. The number of swaps is the number of operations needed at that level.
+
+The time complexity is $O(n \times \log n)$. Here, $n$ is the number of nodes in the binary tree.
+
### **Python3**
diff --git a/solution/2400-2499/2472.Maximum Number of Non-overlapping Palindrome Substrings/README_EN.md b/solution/2400-2499/2472.Maximum Number of Non-overlapping Palindrome Substrings/README_EN.md
index 5393cb8f1238b..28f62c59d3d7b 100644
--- a/solution/2400-2499/2472.Maximum Number of Non-overlapping Palindrome Substrings/README_EN.md
+++ b/solution/2400-2499/2472.Maximum Number of Non-overlapping Palindrome Substrings/README_EN.md
@@ -45,6 +45,23 @@ It can be shown that we cannot find a selection with more than two valid substri
## Solutions
+**Solution 1: Preprocessing + Memoization Search**
+
+First, preprocess the string $s$ to get $dp[i][j]$, which represents whether the substring $s[i,..j]$ is a palindrome.
+
+Then, define a function $dfs(i)$ to represent the maximum number of non-overlapping palindrome substrings that can be selected from the substring $s[i,..]$, i.e.,
+
+$$
+\begin{aligned}
+dfs(i) &= \begin{cases}
+0, & i \geq n \\
+\max\{dfs(i + 1), \max_{j \geq i + k - 1} \{dfs(j + 1) + 1\}\}, & i < n
+\end{cases}
+\end{aligned}
+$$
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string $s$.
+
### **Python3**
diff --git a/solution/2400-2499/2473.Minimum Cost to Buy Apples/README_EN.md b/solution/2400-2499/2473.Minimum Cost to Buy Apples/README_EN.md
index 951562330990d..29cb6ca5d0042 100644
--- a/solution/2400-2499/2473.Minimum Cost to Buy Apples/README_EN.md
+++ b/solution/2400-2499/2473.Minimum Cost to Buy Apples/README_EN.md
@@ -50,6 +50,12 @@
## Solutions
+**Solution 1: Heap-optimized Dijkstra's Algorithm**
+
+We enumerate the starting point, and for each starting point, we use Dijkstra's algorithm to find the shortest distance to all other points, and update the minimum value accordingly.
+
+The time complexity is $O(n \times m \times \log m)$, where $n$ and $m$ are the number of cities and roads, respectively.
+
### **Python3**
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md
index 4929bce998be1..8dcbbb98254ff 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md
@@ -62,6 +62,16 @@
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $words$ 的长度。
+**方法二:模拟(空间优化)**
+
+我们首先判断 $words$ 中的字符串个数是否等于 $s$ 的长度,如果不等于,那么 $s$ 一定不是 $words$ 的首字母缩略词,直接返回 $false$。
+
+然后我们遍历 $s$ 的每个字符,判断其是否等于 $words$ 中对应字符串的首字母,如果不等于,那么 $s$ 一定不是 $words$ 的首字母缩略词,直接返回 $false$。
+
+遍历结束后,如果没有返回 $false$,那么 $s$ 就是 $words$ 的首字母缩略词,返回 $true$。
+
+时间复杂度 $O(n)$,其中 $n$ 是数组 $words$ 的长度。空间复杂度 $O(1)$。
+
### **Python3**
@@ -74,6 +84,12 @@ class Solution:
return "".join(w[0] for w in words) == s
```
+```python
+class Solution:
+ def isAcronym(self, words: List[str], s: str) -> bool:
+ return len(words) == len(s) and all(w[0] == c for w, c in zip(words, s))
+```
+
### **Java**
@@ -90,6 +106,22 @@ class Solution {
}
```
+```java
+class Solution {
+ public boolean isAcronym(List words, String s) {
+ if (words.size() != s.length()) {
+ return false;
+ }
+ for (int i = 0; i < s.length(); ++i) {
+ if (words.get(i).charAt(0) != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+```
+
### **C++**
```cpp
@@ -105,6 +137,23 @@ public:
};
```
+```cpp
+class Solution {
+public:
+ bool isAcronym(vector& words, string s) {
+ if (words.size() != s.size()) {
+ return false;
+ }
+ for (int i = 0; i < s.size(); ++i) {
+ if (words[i][0] != s[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+```
+
### **Go**
```go
@@ -117,6 +166,20 @@ func isAcronym(words []string, s string) bool {
}
```
+```go
+func isAcronym(words []string, s string) bool {
+ if len(words) != len(s) {
+ return false
+ }
+ for i := range s {
+ if words[i][0] != s[i] {
+ return false
+ }
+ }
+ return true
+}
+```
+
### **TypeScript**
```ts
@@ -125,6 +188,49 @@ function isAcronym(words: string[], s: string): boolean {
}
```
+```ts
+function isAcronym(words: string[], s: string): boolean {
+ if (words.length !== s.length) {
+ return false;
+ }
+ for (let i = 0; i < words.length; i++) {
+ if (words[i][0] !== s[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+```
+
+### **Rust**
+
+```rust
+impl Solution {
+ pub fn is_acronym(words: Vec, s: String) -> bool {
+ words
+ .iter()
+ .map(|w| w.chars().next().unwrap_or_default())
+ .collect::() == s
+ }
+}
+```
+
+```rust
+impl Solution {
+ pub fn is_acronym(words: Vec, s: String) -> bool {
+ if words.len() != s.len() {
+ return false;
+ }
+ for (i, w) in words.iter().enumerate() {
+ if w.chars().next().unwrap_or_default() != s.chars().nth(i).unwrap_or_default() {
+ return false;
+ }
+ }
+ true
+ }
+}
+```
+
### **...**
```
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md
index df7ee4dd28969..a8ca51fc143dd 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md
@@ -52,10 +52,20 @@ Hence, s = "ngguoy" is the acronym.
**Solution 1: Simulation**
-We can traverse each string in the array $words$, concatenate their first letters to form a new string $t$, and then check if $t$ is equal to $s$.
+We can iterate over each string in the array $words$, concatenate their first letters to form a new string $t$, and then check if $t$ is equal to $s$.
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $words$.
+**Solution 2: Simulation (Space Optimization)**
+
+First, we check if the number of strings in $words$ is equal to the length of $s$. If not, $s$ is definitely not an acronym of the first letters of $words$, and we directly return $false$.
+
+Then, we iterate over each character in $s$, checking if it is equal to the first letter of the corresponding string in $words$. If not, $s$ is definitely not an acronym of the first letters of $words$, and we directly return $false$.
+
+After the iteration, if we haven't returned $false$, then $s$ is an acronym of the first letters of $words$, and we return $true$.
+
+The time complexity is $O(n)$, where $n$ is the length of the array $words$. The space complexity is $O(1)$.
+
### **Python3**
@@ -66,6 +76,12 @@ class Solution:
return "".join(w[0] for w in words) == s
```
+```python
+class Solution:
+ def isAcronym(self, words: List[str], s: str) -> bool:
+ return len(words) == len(s) and all(w[0] == c for w, c in zip(words, s))
+```
+
### **Java**
```java
@@ -80,6 +96,22 @@ class Solution {
}
```
+```java
+class Solution {
+ public boolean isAcronym(List words, String s) {
+ if (words.size() != s.length()) {
+ return false;
+ }
+ for (int i = 0; i < s.length(); ++i) {
+ if (words.get(i).charAt(0) != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+```
+
### **C++**
```cpp
@@ -95,6 +127,23 @@ public:
};
```
+```cpp
+class Solution {
+public:
+ bool isAcronym(vector& words, string s) {
+ if (words.size() != s.size()) {
+ return false;
+ }
+ for (int i = 0; i < s.size(); ++i) {
+ if (words[i][0] != s[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+```
+
### **Go**
```go
@@ -107,6 +156,20 @@ func isAcronym(words []string, s string) bool {
}
```
+```go
+func isAcronym(words []string, s string) bool {
+ if len(words) != len(s) {
+ return false
+ }
+ for i := range s {
+ if words[i][0] != s[i] {
+ return false
+ }
+ }
+ return true
+}
+```
+
### **TypeScript**
```ts
@@ -115,6 +178,49 @@ function isAcronym(words: string[], s: string): boolean {
}
```
+```ts
+function isAcronym(words: string[], s: string): boolean {
+ if (words.length !== s.length) {
+ return false;
+ }
+ for (let i = 0; i < words.length; i++) {
+ if (words[i][0] !== s[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+```
+
+### **Rust**
+
+```rust
+impl Solution {
+ pub fn is_acronym(words: Vec, s: String) -> bool {
+ words
+ .iter()
+ .map(|w| w.chars().next().unwrap_or_default())
+ .collect::() == s
+ }
+}
+```
+
+```rust
+impl Solution {
+ pub fn is_acronym(words: Vec, s: String) -> bool {
+ if words.len() != s.len() {
+ return false;
+ }
+ for (i, w) in words.iter().enumerate() {
+ if w.chars().next().unwrap_or_default() != s.chars().nth(i).unwrap_or_default() {
+ return false;
+ }
+ }
+ true
+ }
+}
+```
+
### **...**
```
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp
index eda07254e5097..404f4a47ff27f 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp
@@ -1,10 +1,14 @@
class Solution {
public:
bool isAcronym(vector& words, string s) {
- string t;
- for (auto& w : words) {
- t += w[0];
+ if (words.size() != s.size()) {
+ return false;
}
- return t == s;
+ for (int i = 0; i < s.size(); ++i) {
+ if (words[i][0] != s[i]) {
+ return false;
+ }
+ }
+ return true;
}
};
\ No newline at end of file
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go
index d988e77097bec..0b489df8faff1 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go
@@ -1,7 +1,11 @@
func isAcronym(words []string, s string) bool {
- t := []byte{}
- for _, w := range words {
- t = append(t, w[0])
+ if len(words) != len(s) {
+ return false
}
- return string(t) == s
+ for i := range s {
+ if words[i][0] != s[i] {
+ return false
+ }
+ }
+ return true
}
\ No newline at end of file
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java
index 627c1d33530ad..2407554f77a39 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java
@@ -1,9 +1,13 @@
class Solution {
public boolean isAcronym(List words, String s) {
- StringBuilder t = new StringBuilder();
- for (var w : words) {
- t.append(w.charAt(0));
+ if (words.size() != s.length()) {
+ return false;
}
- return t.toString().equals(s);
+ for (int i = 0; i < s.length(); ++i) {
+ if (words.get(i).charAt(0) != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
}
}
\ No newline at end of file
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py
index 3337eb558751d..0285f88e866b6 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py
@@ -1,3 +1,3 @@
class Solution:
def isAcronym(self, words: List[str], s: str) -> bool:
- return "".join(w[0] for w in words) == s
+ return len(words) == len(s) and all(w[0] == c for w, c in zip(words, s))
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.rs b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.rs
new file mode 100644
index 0000000000000..e81d4986a82f3
--- /dev/null
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.rs
@@ -0,0 +1,13 @@
+impl Solution {
+ pub fn is_acronym(words: Vec, s: String) -> bool {
+ if words.len() != s.len() {
+ return false;
+ }
+ for (i, word) in words.iter().enumerate() {
+ if word.chars().next().unwrap_or_default() != s.chars().nth(i).unwrap_or_default() {
+ return false;
+ }
+ }
+ true
+ }
+}
diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts
index a1ef3f8a24b8d..6517403796161 100644
--- a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts
+++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts
@@ -1,3 +1,11 @@
function isAcronym(words: string[], s: string): boolean {
- return words.map(w => w[0]).join('') === s;
+ if (words.length !== s.length) {
+ return false;
+ }
+ for (let i = 0; i < words.length; i++) {
+ if (words[i][0] !== s[i]) {
+ return false;
+ }
+ }
+ return true;
}
diff --git a/solution/config.py b/solution/config.py
index e68738a785653..d294ac1d000b0 100644
--- a/solution/config.py
+++ b/solution/config.py
@@ -50,6 +50,7 @@
2303,
2353,
2362,
+ 2422,
2488,
2525,
2578,
From 8eef40249a24034986d5a9c57fd587f2b309935c Mon Sep 17 00:00:00 2001
From: Libin YANG
Date: Tue, 12 Dec 2023 17:16:53 +0800
Subject: [PATCH 5/5] feat: add solutions to lc problem: No.2200 (#2090)
No.2200.Find All K-Distant Indices in an Array
---
.../README.md | 253 ++++++++++++++++--
.../README_EN.md | 253 ++++++++++++++++--
.../Solution.cpp | 30 +--
.../Solution.go | 24 +-
.../Solution.java | 28 +-
.../Solution.py | 20 +-
.../Solution.ts | 15 +-
7 files changed, 516 insertions(+), 107 deletions(-)
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md
index 9a9f0f4eac49a..f238564b5fec8 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md
@@ -52,6 +52,26 @@
+**方法一:枚举**
+
+我们在 $[0, n)$ 的范围内枚举下标 $i$,对于每个下标 $i$,我们在 $[0, n)$ 的范围内枚举下标 $j$,如果 $|i - j| \leq k$ 且 $nums[j] == key$,那么 $i$ 就是一个 K 近邻下标,我们将 $i$ 加入答案数组中,然后跳出内层循环,枚举下一个下标 $i$。
+
+时间复杂度 $O(n^2)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。
+
+**方法二:预处理 + 二分查找**
+
+我们可以预处理得到所有等于 $key$ 的元素的下标,记录在数组 $idx$ 中。数组 $idx$ 中的所有下标元素是按照升序排列的,
+
+接下来,我们枚举下标 $i$,对于每个下标 $i$,我们可以使用二分查找的方法在数组 $idx$ 中查找 $[i - k, i + k]$ 范围内的元素,如果存在元素,那么 $i$ 就是一个 K 近邻下标,我们将 $i$ 加入答案数组中。
+
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
+
+**方法三:双指针**
+
+我们枚举下标 $i$,用一个指针 $j$ 指向满足 $j \geq i - k$ 且 $nums[j] = key$ 的最小下标,如果 $j$ 存在且 $j \leq i + k$,那么 $i$ 就是一个 K 近邻下标,我们将 $i$ 加入答案数组中。
+
+时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。
+
### **Python3**
@@ -64,10 +84,34 @@ class Solution:
ans = []
n = len(nums)
for i in range(n):
- for j in range(n):
- if abs(i - j) <= k and nums[j] == key:
- ans.append(i)
- break
+ if any(abs(i - j) <= k and nums[j] == key for j in range(n)):
+ ans.append(i)
+ return ans
+```
+
+```python
+class Solution:
+ def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
+ idx = [i for i, x in enumerate(nums) if x == key]
+ ans = []
+ for i in range(len(nums)):
+ l = bisect_left(idx, i - k)
+ r = bisect_right(idx, i + k) - 1
+ if l <= r:
+ ans.append(i)
+ return ans
+```
+
+```python
+class Solution:
+ def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
+ ans = []
+ j, n = 0, len(nums)
+ for i in range(n):
+ while j < i - k or (j < n and nums[j] != key):
+ j += 1
+ if j < n and j <= (i + k):
+ ans.append(i)
return ans
```
@@ -93,22 +137,45 @@ class Solution {
}
```
-### **TypeScript**
+```java
+class Solution {
+ public List findKDistantIndices(int[] nums, int key, int k) {
+ List idx = new ArrayList<>();
+ for (int i = 0; i < nums.length; i++) {
+ if (nums[i] == key) {
+ idx.add(i);
+ }
+ }
+ List ans = new ArrayList<>();
+ for (int i = 0; i < nums.length; ++i) {
+ int l = Collections.binarySearch(idx, i - k);
+ int r = Collections.binarySearch(idx, i + k + 1);
+ l = l < 0 ? -l - 1 : l;
+ r = r < 0 ? -r - 2 : r - 1;
+ if (l <= r) {
+ ans.add(i);
+ }
+ }
+ return ans;
+ }
+}
+```
-```ts
-function findKDistantIndices(nums: number[], key: number, k: number): number[] {
- const n = nums.length;
- let ans = [];
- for (let j = 0; j < n; j++) {
- if (nums[j] == key) {
- for (let i = j - k; i <= j + k; i++) {
- if (i >= 0 && i < n && !ans.includes(i)) {
- ans.push(i);
- }
+```java
+class Solution {
+ public List findKDistantIndices(int[] nums, int key, int k) {
+ int n = nums.length;
+ List ans = new ArrayList<>();
+ for (int i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] != key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.add(i);
}
}
+ return ans;
}
- return ans;
}
```
@@ -133,15 +200,56 @@ public:
};
```
+```cpp
+class Solution {
+public:
+ vector findKDistantIndices(vector& nums, int key, int k) {
+ vector idx;
+ int n = nums.size();
+ for (int i = 0; i < n; ++i) {
+ if (nums[i] == key) {
+ idx.push_back(i);
+ }
+ }
+ vector ans;
+ for (int i = 0; i < n; ++i) {
+ auto it1 = lower_bound(idx.begin(), idx.end(), i - k);
+ auto it2 = upper_bound(idx.begin(), idx.end(), i + k) - 1;
+ if (it1 <= it2) {
+ ans.push_back(i);
+ }
+ }
+ return ans;
+ }
+};
+```
+
+```cpp
+class Solution {
+public:
+ vector findKDistantIndices(vector& nums, int key, int k) {
+ int n = nums.size();
+ vector ans;
+ for (int i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] != key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.push_back(i);
+ }
+ }
+ return ans;
+ }
+};
+```
+
### **Go**
```go
-func findKDistantIndices(nums []int, key int, k int) []int {
- n := len(nums)
- var ans []int
- for i := 0; i < n; i++ {
- for j, v := range nums {
- if abs(i-j) <= k && v == key {
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
+ for i := range nums {
+ for j, x := range nums {
+ if abs(i-j) <= k && x == key {
ans = append(ans, i)
break
}
@@ -158,6 +266,107 @@ func abs(x int) int {
}
```
+```go
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
+ idx := []int{}
+ for i, x := range nums {
+ if x == key {
+ idx = append(idx, i)
+ }
+ }
+ for i := range nums {
+ l := sort.SearchInts(idx, i-k)
+ r := sort.SearchInts(idx, i+k+1) - 1
+ if l <= r {
+ ans = append(ans, i)
+ }
+ }
+ return
+}
+```
+
+```go
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
+ n := len(nums)
+ for i, j := 0, 0; i < n; i++ {
+ for j < i-k || (j < n && nums[j] != key) {
+ j++
+ }
+ if j < n && j <= i+k {
+ ans = append(ans, i)
+ }
+ }
+ return
+}
+```
+
+### **TypeScript**
+
+```ts
+function findKDistantIndices(nums: number[], key: number, k: number): number[] {
+ const n = nums.length;
+ const ans: number[] = [];
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < n; ++j) {
+ if (Math.abs(i - j) <= k && nums[j] === key) {
+ ans.push(i);
+ break;
+ }
+ }
+ }
+ return ans;
+}
+```
+
+```ts
+function findKDistantIndices(nums: number[], key: number, k: number): number[] {
+ const n = nums.length;
+ const idx: number[] = [];
+ for (let i = 0; i < n; i++) {
+ if (nums[i] === key) {
+ idx.push(i);
+ }
+ }
+ const search = (x: number): number => {
+ let [l, r] = [0, idx.length];
+ while (l < r) {
+ const mid = (l + r) >> 1;
+ if (idx[mid] >= x) {
+ r = mid;
+ } else {
+ l = mid + 1;
+ }
+ }
+ return l;
+ };
+ const ans: number[] = [];
+ for (let i = 0; i < n; ++i) {
+ const l = search(i - k);
+ const r = search(i + k + 1) - 1;
+ if (l <= r) {
+ ans.push(i);
+ }
+ }
+ return ans;
+}
+```
+
+```ts
+function findKDistantIndices(nums: number[], key: number, k: number): number[] {
+ const n = nums.length;
+ const ans: number[] = [];
+ for (let i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] !== key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.push(i);
+ }
+ }
+ return ans;
+}
+```
+
### **...**
```
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md
index e3a313b2917f7..c54cd518a8b59 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md
@@ -46,6 +46,26 @@ Hence, we return [0,1,2,3,4].
## Solutions
+**Solution 1: Enumeration**
+
+We enumerate the index $i$ in the range $[0, n)$, and for each index $i$, we enumerate the index $j$ in the range $[0, n)$. If $|i - j| \leq k$ and $nums[j] == key$, then $i$ is a K-nearest neighbor index. We add $i$ to the answer array, then break the inner loop and enumerate the next index $i$.
+
+The time complexity is $O(n^2)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$.
+
+**Solution 2: Preprocessing + Binary Search**
+
+We can preprocess to get the indices of all elements equal to $key$, recorded in the array $idx$. All index elements in the array $idx$ are sorted in ascending order.
+
+Next, we enumerate the index $i$. For each index $i$, we can use binary search to find elements in the range $[i - k, i + k]$ in the array $idx$. If there are elements, then $i$ is a K-nearest neighbor index. We add $i$ to the answer array.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
+
+**Solution 3: Two Pointers**
+
+We enumerate the index $i$, and use a pointer $j$ to point to the smallest index that satisfies $j \geq i - k$ and $nums[j] = key$. If $j$ exists and $j \leq i + k$, then $i$ is a K-nearest neighbor index. We add $i$ to the answer array.
+
+The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$.
+
### **Python3**
@@ -56,10 +76,34 @@ class Solution:
ans = []
n = len(nums)
for i in range(n):
- for j in range(n):
- if abs(i - j) <= k and nums[j] == key:
- ans.append(i)
- break
+ if any(abs(i - j) <= k and nums[j] == key for j in range(n)):
+ ans.append(i)
+ return ans
+```
+
+```python
+class Solution:
+ def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
+ idx = [i for i, x in enumerate(nums) if x == key]
+ ans = []
+ for i in range(len(nums)):
+ l = bisect_left(idx, i - k)
+ r = bisect_right(idx, i + k) - 1
+ if l <= r:
+ ans.append(i)
+ return ans
+```
+
+```python
+class Solution:
+ def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
+ ans = []
+ j, n = 0, len(nums)
+ for i in range(n):
+ while j < i - k or (j < n and nums[j] != key):
+ j += 1
+ if j < n and j <= (i + k):
+ ans.append(i)
return ans
```
@@ -83,22 +127,45 @@ class Solution {
}
```
-### **TypeScript**
+```java
+class Solution {
+ public List findKDistantIndices(int[] nums, int key, int k) {
+ List idx = new ArrayList<>();
+ for (int i = 0; i < nums.length; i++) {
+ if (nums[i] == key) {
+ idx.add(i);
+ }
+ }
+ List ans = new ArrayList<>();
+ for (int i = 0; i < nums.length; ++i) {
+ int l = Collections.binarySearch(idx, i - k);
+ int r = Collections.binarySearch(idx, i + k + 1);
+ l = l < 0 ? -l - 1 : l;
+ r = r < 0 ? -r - 2 : r - 1;
+ if (l <= r) {
+ ans.add(i);
+ }
+ }
+ return ans;
+ }
+}
+```
-```ts
-function findKDistantIndices(nums: number[], key: number, k: number): number[] {
- const n = nums.length;
- let ans = [];
- for (let j = 0; j < n; j++) {
- if (nums[j] == key) {
- for (let i = j - k; i <= j + k; i++) {
- if (i >= 0 && i < n && !ans.includes(i)) {
- ans.push(i);
- }
+```java
+class Solution {
+ public List findKDistantIndices(int[] nums, int key, int k) {
+ int n = nums.length;
+ List ans = new ArrayList<>();
+ for (int i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] != key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.add(i);
}
}
+ return ans;
}
- return ans;
}
```
@@ -123,15 +190,56 @@ public:
};
```
+```cpp
+class Solution {
+public:
+ vector findKDistantIndices(vector& nums, int key, int k) {
+ vector idx;
+ int n = nums.size();
+ for (int i = 0; i < n; ++i) {
+ if (nums[i] == key) {
+ idx.push_back(i);
+ }
+ }
+ vector ans;
+ for (int i = 0; i < n; ++i) {
+ auto it1 = lower_bound(idx.begin(), idx.end(), i - k);
+ auto it2 = upper_bound(idx.begin(), idx.end(), i + k) - 1;
+ if (it1 <= it2) {
+ ans.push_back(i);
+ }
+ }
+ return ans;
+ }
+};
+```
+
+```cpp
+class Solution {
+public:
+ vector findKDistantIndices(vector& nums, int key, int k) {
+ int n = nums.size();
+ vector ans;
+ for (int i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] != key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.push_back(i);
+ }
+ }
+ return ans;
+ }
+};
+```
+
### **Go**
```go
-func findKDistantIndices(nums []int, key int, k int) []int {
- n := len(nums)
- var ans []int
- for i := 0; i < n; i++ {
- for j, v := range nums {
- if abs(i-j) <= k && v == key {
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
+ for i := range nums {
+ for j, x := range nums {
+ if abs(i-j) <= k && x == key {
ans = append(ans, i)
break
}
@@ -148,6 +256,107 @@ func abs(x int) int {
}
```
+```go
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
+ idx := []int{}
+ for i, x := range nums {
+ if x == key {
+ idx = append(idx, i)
+ }
+ }
+ for i := range nums {
+ l := sort.SearchInts(idx, i-k)
+ r := sort.SearchInts(idx, i+k+1) - 1
+ if l <= r {
+ ans = append(ans, i)
+ }
+ }
+ return
+}
+```
+
+```go
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
+ n := len(nums)
+ for i, j := 0, 0; i < n; i++ {
+ for j < i-k || (j < n && nums[j] != key) {
+ j++
+ }
+ if j < n && j <= i+k {
+ ans = append(ans, i)
+ }
+ }
+ return
+}
+```
+
+### **TypeScript**
+
+```ts
+function findKDistantIndices(nums: number[], key: number, k: number): number[] {
+ const n = nums.length;
+ const ans: number[] = [];
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < n; ++j) {
+ if (Math.abs(i - j) <= k && nums[j] === key) {
+ ans.push(i);
+ break;
+ }
+ }
+ }
+ return ans;
+}
+```
+
+```ts
+function findKDistantIndices(nums: number[], key: number, k: number): number[] {
+ const n = nums.length;
+ const idx: number[] = [];
+ for (let i = 0; i < n; i++) {
+ if (nums[i] === key) {
+ idx.push(i);
+ }
+ }
+ const search = (x: number): number => {
+ let [l, r] = [0, idx.length];
+ while (l < r) {
+ const mid = (l + r) >> 1;
+ if (idx[mid] >= x) {
+ r = mid;
+ } else {
+ l = mid + 1;
+ }
+ }
+ return l;
+ };
+ const ans: number[] = [];
+ for (let i = 0; i < n; ++i) {
+ const l = search(i - k);
+ const r = search(i + k + 1) - 1;
+ if (l <= r) {
+ ans.push(i);
+ }
+ }
+ return ans;
+}
+```
+
+```ts
+function findKDistantIndices(nums: number[], key: number, k: number): number[] {
+ const n = nums.length;
+ const ans: number[] = [];
+ for (let i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] !== key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.push(i);
+ }
+ }
+ return ans;
+}
+```
+
### **...**
```
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp
index d5fa87ca2d76a..58c3adb6840c8 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp
@@ -1,16 +1,16 @@
-class Solution {
-public:
- vector findKDistantIndices(vector& nums, int key, int k) {
- int n = nums.size();
- vector ans;
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- if (abs(i - j) <= k && nums[j] == key) {
- ans.push_back(i);
- break;
- }
- }
- }
- return ans;
- }
+class Solution {
+public:
+ vector findKDistantIndices(vector& nums, int key, int k) {
+ int n = nums.size();
+ vector ans;
+ for (int i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] != key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.push_back(i);
+ }
+ }
+ return ans;
+ }
};
\ No newline at end of file
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go
index 387499f236a09..9f87a7fe27a93 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go
@@ -1,20 +1,12 @@
-func findKDistantIndices(nums []int, key int, k int) []int {
+func findKDistantIndices(nums []int, key int, k int) (ans []int) {
n := len(nums)
- var ans []int
- for i := 0; i < n; i++ {
- for j, v := range nums {
- if abs(i-j) <= k && v == key {
- ans = append(ans, i)
- break
- }
+ for i, j := 0, 0; i < n; i++ {
+ for j < i-k || (j < n && nums[j] != key) {
+ j++
+ }
+ if j < n && j <= i+k {
+ ans = append(ans, i)
}
}
- return ans
-}
-
-func abs(x int) int {
- if x < 0 {
- return -x
- }
- return x
+ return
}
\ No newline at end of file
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java
index 4e3632276d4c5..9dddaba757419 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java
@@ -1,15 +1,15 @@
-class Solution {
- public List findKDistantIndices(int[] nums, int key, int k) {
- int n = nums.length;
- List ans = new ArrayList<>();
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- if (Math.abs(i - j) <= k && nums[j] == key) {
- ans.add(i);
- break;
- }
- }
- }
- return ans;
- }
+class Solution {
+ public List findKDistantIndices(int[] nums, int key, int k) {
+ int n = nums.length;
+ List ans = new ArrayList<>();
+ for (int i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] != key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.add(i);
+ }
+ }
+ return ans;
+ }
}
\ No newline at end of file
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py
index 79e0217d9cf33..b552876bbed4e 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py
@@ -1,10 +1,10 @@
-class Solution:
- def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
- ans = []
- n = len(nums)
- for i in range(n):
- for j in range(n):
- if abs(i - j) <= k and nums[j] == key:
- ans.append(i)
- break
- return ans
+class Solution:
+ def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
+ ans = []
+ j, n = 0, len(nums)
+ for i in range(n):
+ while j < i - k or (j < n and nums[j] != key):
+ j += 1
+ if j < n and j <= (i + k):
+ ans.append(i)
+ return ans
diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts
index ec9507f3f68f5..85fd8fe4a5796 100644
--- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts
+++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts
@@ -1,13 +1,12 @@
function findKDistantIndices(nums: number[], key: number, k: number): number[] {
const n = nums.length;
- let ans = [];
- for (let j = 0; j < n; j++) {
- if (nums[j] == key) {
- for (let i = j - k; i <= j + k; i++) {
- if (i >= 0 && i < n && !ans.includes(i)) {
- ans.push(i);
- }
- }
+ const ans: number[] = [];
+ for (let i = 0, j = 0; i < n; ++i) {
+ while (j < i - k || (j < n && nums[j] !== key)) {
+ ++j;
+ }
+ if (j < n && j <= i + k) {
+ ans.push(i);
}
}
return ans;