Skip to content

feat: add solutions to lc problems: No.200+ #2180

New issue

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

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

Already on GitHub? Sign in to your account

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions solution/0200-0299/0213.House Robber II/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Total amount you can rob = 1 + 3 = 4.

## Solutions

**Solution 1: Dynamic Programming**

The circular arrangement means that at most one of the first and last houses can be chosen for theft, so this circular arrangement problem can be reduced to two single-row house problems.

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

<!-- tabs:start -->

### **Python3**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@

**方法一:排序**

将数组 $nums$ 升序排列,然后获取 $nums[n-k]$。
我们可以将数组 $nums$ 升序排列,然后获取 $nums[n-k]$。

时间复杂度 $O(nlogn)$,其中 $n$ 表示数组 $nums$ 的长度。
时间复杂度 $O(n \times \log n)$,其中 $n$ 表示数组 $nums$ 的长度。

**方法二:partition**
**方法二:Partition**

并不是所有时候,都需要整个数组进入有序状态,只需要**局部有序**,或者说,从大到小排序,只要 $[0..k)$ 位置的元素有序,那么就能确定结果,此处使用**快速排序**。
我们注意到,并不是所有时候,都需要整个数组进入有序状态,只需要**局部有序**,或者说,从大到小排序,只要 $[0..k)$ 位置的元素有序,那么就能确定结果,此处使用**快速排序**。

快速排序有一特点,每一次循环结束时,能够确定的是$partition$ 一定处于它该处于的索引位置。从而根据它得知,结果值是在左数组还是在右数组当中,然后对那一数组进行排序即可。
快速排序有一特点,每一次循环结束时,能够确定的是 $partition$ 一定处于它该处于的索引位置。从而根据它得知,结果值是在左数组还是在右数组当中,然后对那一数组进行排序即可。

时间复杂度 $O(n)$,其中 $n$ 表示数组 $nums$ 的长度。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@

## Solutions

**Solution 1: Sorting**

We can sort the array $nums$ in ascending order, and then get $nums[n-k]$.

The time complexity is $O(n \times \log n)$, where $n$ is the length of the array $nums$.

**Solution 2: Partition**

We notice that it is not always necessary for the entire array to be in an ordered state. We only need **local order**. That is to say, if the elements in the position $[0..k)$ are sorted in descending order, then we can determine the result. Here we use **quick sort**.

Quick sort has a characteristic that at the end of each loop, it can be determined that the $partition$ is definitely at the index position it should be. Therefore, based on it, we know whether the result value is in the left array or in the right array, and then sort that array.

The time complexity is $O(n)$, where $n$ is the length of the array $nums$.

<!-- tabs:start -->

### **Python3**
Expand Down
16 changes: 16 additions & 0 deletions solution/0200-0299/0217.Contains Duplicate/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@

## Solutions

**Solution 1: Sorting**

First, we sort the array `nums`.

Then, we traverse the array. If there are two adjacent elements that are the same, it means that there are duplicate elements in the array, and we directly return `true`.

Otherwise, when the traversal ends, we return `false`.

The time complexity is $O(n \times \log n)$, where $n$ is the length of the array `nums`.

**Solution 2: Hash Table**

We traverse the array and record the elements that have appeared in the hash table $s$. If an element appears for the second time, it means that there are duplicate elements in the array, and we directly return `true`.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array `nums`.

<!-- tabs:start -->

### **Python3**
Expand Down
4 changes: 2 additions & 2 deletions solution/0200-0299/0220.Contains Duplicate III/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ abs(nums[i] - nums[j]) &lt;= valueDiff --&gt; abs(1 - 1) &lt;= 0

**方法一:滑动窗口 + 有序集合**

维护一个大小为 $k$ 的滑动窗口,窗口中的元素保持有序。
我们维护一个大小为 $k$ 的滑动窗口,窗口中的元素保持有序。

遍历数组 `nums`,对于每个元素 $nums[i]$,我们在有序集合中查找第一个大于等于 $nums[i] - t$ 的元素,如果元素存在,并且该元素小于等于 $nums[i] + t$,说明找到了一对符合条件的元素,返回 `true`。否则,我们将 $nums[i]$ 插入到有序集合中,并且如果有序集合的大小超过了 $k$,我们需要将最早加入有序集合的元素删除。

时间复杂度 $O(n\times \log k)$,其中 $n$ 是数组 `nums` 的长度。对于每个元素,我们需要 $O(\log k)$ 的时间来查找有序集合中的元素,一共有 $n$ 个元素,因此总时间复杂度是 $O(n\times \log k)$。
时间复杂度 $O(n \times \log k)$,其中 $n$ 是数组 `nums` 的长度。对于每个元素,我们需要 $O(\log k)$ 的时间来查找有序集合中的元素,一共有 $n$ 个元素,因此总时间复杂度是 $O(n \times \log k)$。

<!-- tabs:start -->

Expand Down
8 changes: 8 additions & 0 deletions solution/0200-0299/0220.Contains Duplicate III/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ abs(nums[i] - nums[j]) &lt;= valueDiff --&gt; abs(1 - 1) &lt;= 0

## Solutions

**Solution 1: Sliding Window + Ordered Set**

We maintain a sliding window of size $k$, and the elements in the window are kept in order.

We traverse the array `nums`. For each element $nums[i]$, we look for the first element in the ordered set that is greater than or equal to $nums[i] - t$. If the element exists, and this element is less than or equal to $nums[i] + t$, it means we have found a pair of elements that meet the conditions, and we return `true`. Otherwise, we insert $nums[i]$ into the ordered set, and if the size of the ordered set exceeds $k$, we need to remove the earliest added element from the ordered set.

The time complexity is $O(n \times \log k)$, where $n$ is the length of the array `nums`. For each element, we need $O(\log k)$ time to find the element in the ordered set, and there are $n$ elements in total, so the total time complexity is $O(n \times \log k)$.

<!-- tabs:start -->

### **Python3**
Expand Down
16 changes: 16 additions & 0 deletions solution/0200-0299/0221.Maximal Square/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@

## Solutions

**Solution 1: Dynamic Programming**

We define $dp[i + 1][j + 1]$ as the maximum square side length with the lower right corner at index $(i, j)$. The answer is the maximum value among all $dp[i + 1][j + 1]$.

The state transition equation is:

$$
dp[i + 1][j + 1] =
\begin{cases}
0 & \text{if } matrix[i][j] = '0' \\
\min(dp[i][j], dp[i][j + 1], dp[i + 1][j]) + 1 & \text{if } matrix[i][j] = '1'
\end{cases}
$$

The time complexity is $O(m\times n)$, and the space complexity is $O(m\times n)$. Where $m$ and $n$ are the number of rows and columns of the matrix, respectively.

<!-- tabs:start -->

### **Python3**
Expand Down
21 changes: 21 additions & 0 deletions solution/0200-0299/0222.Count Complete Tree Nodes/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@

## Solutions

**Solution 1: Recursion**

We recursively traverse the entire tree and count the number of nodes.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the tree.

**Solution 2: Binary Search**

For this problem, we can also take advantage of the characteristics of a complete binary tree to design a faster algorithm.

Characteristics of a complete binary tree: leaf nodes can only appear on the bottom and second-to-bottom layers, and the leaf nodes on the bottom layer are concentrated on the left side of the tree. It should be noted that a full binary tree is definitely a complete binary tree, but a complete binary tree is not necessarily a full binary tree.

If the number of layers in a full binary tree is $h$, then the total number of nodes is $2^h - 1$.

We first count the heights of the left and right subtrees of $root$, denoted as $left$ and $right$.

1. If $left = right$, it means that the left subtree is a full binary tree, so the total number of nodes in the left subtree is $2^{left} - 1$. Plus the $root$ node, it is $2^{left}$. Then we recursively count the right subtree.
1. If $left > right$, it means that the right subtree is a full binary tree, so the total number of nodes in the right subtree is $2^{right} - 1$. Plus the $root$ node, it is $2^{right}$. Then we recursively count the left subtree.

The time complexity is $O(\log^2 n)$.

<!-- tabs:start -->

### **Python3**
Expand Down
6 changes: 6 additions & 0 deletions solution/0200-0299/0223.Rectangle Area/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@

## Solutions

**Solution 1: Calculate Overlapping Area**

First, we calculate the area of the two rectangles separately, denoted as $a$ and $b$. Then we calculate the overlapping width $width$ and height $height$. The overlapping area is $max(width, 0) \times max(height, 0)$. Finally, we subtract the overlapping area from $a$ and $b$.

The time complexity is $O(1)$, and the space complexity is $O(1)$.

<!-- tabs:start -->

### **Python3**
Expand Down
16 changes: 16 additions & 0 deletions solution/0200-0299/0224.Basic Calculator/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@

## Solutions

**Solution 1: Stack**

We use a stack $stk$ to save the current calculation result and operator, a variable $sign$ to save the current sign, and a variable $ans$ to save the final calculation result.

Next, we traverse each character of the string $s$:

- If the current character is a number, we use a loop to read the following consecutive numbers, and then add or subtract it to $ans$ according to the current sign.
- If the current character is `'+'`, we change the variable $sign$ to positive.
- If the current character is `'-'`, we change the variable $sign$ to negative.
- If the current character is `'('`, we push the current $ans$ and $sign$ into the stack, and reset them to empty and 1, and start to calculate the new $ans$ and $sign$.
- If the current character is `')'`, we pop the top two elements of the stack, one is the operator, and the other is the number calculated before the bracket. We multiply the current number by the operator, and add the previous number to get the new $ans$.

After traversing the string $s$, we return $ans$.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string $s$.

<!-- tabs:start -->

### **Python3**
Expand Down
11 changes: 11 additions & 0 deletions solution/0200-0299/0225.Implement Stack using Queues/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ myStack.empty(); // return False

## Solutions

**Solution 1: Two Queues**

We use two queues $q_1$ and $q_2$, where $q_1$ is used to store the elements in the stack, and $q_2$ is used to assist in implementing the stack operations.

- `push` operation: Push the element into $q_2$, then pop the elements in $q_1$ one by one and push them into $q_2$, finally swap the references of $q_1$ and $q_2$. The time complexity is $O(n)$.
- `pop` operation: Directly pop the front element of $q_1$. The time complexity is $O(1)$.
- `top` operation: Directly return the front element of $q_1$. The time complexity is $O(1)$.
- `empty` operation: Check whether $q_1$ is empty. The time complexity is $O(1)$.

The space complexity is $O(n)$, where $n$ is the number of elements in the stack.

<!-- tabs:start -->

### **Python3**
Expand Down
6 changes: 5 additions & 1 deletion solution/0200-0299/0226.Invert Binary Tree/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@

## Solutions

DFS.
**Solution 1: Recursion**

The idea of recursion is very simple, which is to swap the left and right subtrees of the current node, and then recursively swap the left and right subtrees of the current node.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the binary tree.

<!-- tabs:start -->

Expand Down
12 changes: 12 additions & 0 deletions solution/0200-0299/0227.Basic Calculator II/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@

## Solutions

**Solution 1: Stack**

We traverse the string $s$, and use a variable `sign` to record the operator before each number. For the first number, its previous operator is considered as a plus sign. Each time we traverse to the end of a number, we decide the calculation method based on `sign`:

- Plus sign: push the number into the stack;
- Minus sign: push the opposite number into the stack;
- Multiplication and division signs: calculate the number with the top element of the stack, and replace the top element of the stack with the calculation result.

After the traversal ends, the sum of the elements in the stack is the answer.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string $s$.

<!-- tabs:start -->

### **Python3**
Expand Down