Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

feat: add solutions to lc problems: No.1600+ #2119

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
Dec 18, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ nums[3] + nums[0] = 3 + 1 = 4.

可以发现,这实际上是在对一个连续区间内的元素进行加减操作,因此我们可以使用差分数组来实现。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ Therefore, nums[i] + nums[n-1-i] = 4 for every i, so nums is complementary.

## Solutions

**Solution 1: Difference Array**

Let's denote $a$ as the smaller value between $nums[i]$ and $nums[n-i-1]$, and $b$ as the larger value between $nums[i]$ and $nums[n-i-1]$.

Suppose that after replacement, the sum of the two numbers is $x$. From the problem, we know that the minimum value of $x$ is $2$, which means both numbers are replaced by $1$; the maximum value is $2 \times limit$, which means both numbers are replaced by $limit$. Therefore, the range of $x$ is $[2,... 2 \times limit]$.

How to find the minimum number of replacements for different $x$?

We analyze and find:

- If $x = a + b$, then the number of replacements we need is $0$, which means the current pair of numbers already meets the complement requirement;
- Otherwise, if $1 + a \le x \le limit + b $, then the number of replacements we need is $1$, which means we can replace one of the numbers;
- Otherwise, if $2 \le x \le 2 \times limit$, then the number of replacements we need is $2$, which means we need to replace both numbers.

Therefore, we can iterate over each pair of numbers and perform the following operations:

1. First, add $2$ to the number of operations required in the range $[2,... 2 \times limit]$.
1. Then, subtract $1$ from the number of operations required in the range $[1 + a,... limit + b]$.
1. Finally, subtract $1$ from the number of operations required in the range $[a + b,... a + b]$.

We can see that this is actually adding and subtracting elements in a continuous interval, so we can use a difference array to implement it.

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

<!-- tabs:start -->

### **Python3**
Expand Down
12 changes: 12 additions & 0 deletions solution/1600-1699/1675.Minimize Deviation in Array/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@

## Solutions

**Solution 1: Greedy + Priority Queue**

Intuitively, to get the minimum offset of the array, we need to decrease the maximum value of the array and increase the minimum value of the array.

Since there are two operations that can be performed each time: multiply an odd number by $2$; divide an even number by $2$, the situation is more complex. We can multiply all odd numbers by $2$ to convert them into even numbers, which is equivalent to having only one division operation. The division operation can only reduce a certain number, and only by reducing the maximum value can the result be more optimal.

Therefore, we use a priority queue (max heap) to maintain the maximum value of the array. Each time we take out the top element of the heap for division operation, put the new value into the heap, and update the minimum value and the minimum value of the difference between the top element of the heap and the minimum value.

When the top element of the heap is an odd number, the operation stops.

The time complexity is $O(n\log n \times \log m)$. Where $n$ and $m$ are the length of the array `nums` and the maximum element of the array, respectively. Since the maximum element in the array is divided by $2$ at most $O(\log m)$ times, all elements are divided by $2$ at most $O(n\log m)$ times. Each time the heap is popped and put into operation, the time complexity is $O(\log n)$. Therefore, the total time complexity is $O(n\log n \times \log m)$.

<!-- tabs:start -->

### **Python3**
Expand Down
15 changes: 15 additions & 0 deletions solution/1600-1699/1678.Goal Parser Interpretation/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ The final concatenated result is &quot;Goal&quot;.

## Solutions

**Solution 1: String Replacement**

According to the problem, we only need to replace `"()"` with `'o'` and `"(al)"` with `"al"` in the string `command`.

**Solution 2: String Iteration**

We can also iterate over the string `command`. For each character $c$:

- If it is `'G'`, directly add $c$ to the result string;
- If it is `'('`, check if the next character is `')'`. If it is, add `'o'` to the result string. Otherwise, add `"al"` to the result string.

After the iteration, return the result string.

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

<!-- tabs:start -->

### **Python3**
Expand Down
10 changes: 5 additions & 5 deletions solution/1600-1699/1679.Max Number of K-Sum Pairs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

**方法一:排序**

我们对 `nums` 进行排序。然后 $l$, $r$ 分别指向 `nums` 首尾元素,判断两整数之和 $s$ 与 $k$ 的大小关系。
我们对 $nums$ 进行排序。然后 $l$, $r$ 分别指向 $nums$ 首尾元素,判断两整数之和 $s$ 与 $k$ 的大小关系。

- 若 $s = k$,说明找到了两个整数,满足和为 $k$,答案加一,然后 $l$, $r$ 向中间移动;
- 若 $s \gt k$,则 $r$ 指针向左移动;
Expand All @@ -58,17 +58,17 @@

循环结束,返回答案。

时间复杂度 $O(n\times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为 `nums` 的长度。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为 $nums$ 的长度。

**方法二:哈希表**

我们使用哈希表 `cnt` 记录当前剩余整数及其出现的次数。
我们使用哈希表 $cnt$ 记录当前剩余整数及其出现的次数。

遍历 `nums`,对于当前整数 $x$,判断 $k - x$ 是否在 `cnt` 中,若存在,则说明找到了两个整数,满足和为 $k$,答案加一,然后将 $k - x$ 的出现次数减一;否则,将 $x$ 的出现次数加一。
遍历 $nums$,对于当前整数 $x$,判断 $k - x$ 是否在 $cnt$ 中,若存在,则说明找到了两个整数,满足和为 $k$,答案加一,然后将 $k - x$ 的出现次数减一;否则,将 $x$ 的出现次数加一。

遍历结束,返回答案。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 `nums` 的长度。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 $nums$ 的长度。

<!-- tabs:start -->

Expand Down
23 changes: 23 additions & 0 deletions solution/1600-1699/1679.Max Number of K-Sum Pairs/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,29 @@ There are no more pairs that sum up to 6, hence a total of 1 operation.</pre>

## Solutions

**Solution 1: Sorting**

We sort $nums$. Then $l$ and $r$ point to the first and last elements of $nums$ respectively, and we compare the sum $s$ of the two integers with $k$.

- If $s = k$, it means that we have found two integers whose sum is $k$. We increment the answer and then move $l$ and $r$ towards the middle;
- If $s > k$, then we move the $r$ pointer to the left;
- If $s < k$, then we move the $l$ pointer to the right;
- We continue the loop until $l \geq r$.

After the loop ends, we return the answer.

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

**Solution 2: Hash Table**

We use a hash table $cnt$ to record the current remaining integers and their occurrence counts.

We iterate over $nums$. For the current integer $x$, we check if $k - x$ is in $cnt$. If it exists, it means that we have found two integers whose sum is $k$. We increment the answer and then decrement the occurrence count of $k - x$; otherwise, we increment the occurrence count of $x$.

After the iteration ends, we return the answer.

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

<!-- tabs:start -->

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

观察数字的连接规律,我们可以发现,当连接到第 $i$ 个数时,实际上是将前 $i-1$ 个数连接而成的结果 $ans$ 往左移动一定的位数,然后再加上 $i$ 这个数,移动的位数 $shift$ 是 $i$ 中二进制的位数。由于 $i$ 在不断加 $1$,移动的位数要么与上一次移动的位数保持不变,要么加一。当 $i$ 为 $2$ 的幂次方的时候,也即是说 $i$ 的二进制数中只有一位是 $1$ 时,移动的位数相比于上次加 $1$。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为给定的整数
时间复杂度 $O(n)$,其中 $n$ 为给定的整数。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ After modulo 10<sup>9</sup> + 7, the result is 505379714.

## Solutions

**Solution 1: Bit Manipulation**

By observing the pattern of number concatenation, we can find that when concatenating to the $i$-th number, the result $ans$ formed by concatenating the previous $i-1$ numbers is actually shifted to the left by a certain number of bits, and then $i$ is added. The number of bits shifted, $shift$, is the number of binary digits in $i$. Since $i$ is continuously incremented by $1$, the number of bits shifted either remains the same as the last shift or increases by one. When $i$ is a power of $2$, that is, when there is only one bit in the binary number of $i$ that is $1$, the number of bits shifted increases by $1$ compared to the last time.

The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$.

<!-- tabs:start -->

### **Python3**
Expand Down
16 changes: 16 additions & 0 deletions solution/1600-1699/1681.Minimum Incompatibility/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ The incompatibility is (2-1) + (3-2) + (8-6) + (3-1) = 6.

## Solutions

**Solution 1: Preprocessing + State Compression + Dynamic Programming**

Let's assume that the size of each subset after partitioning is $m$, so $m=\frac{n}{k}$, where $n$ is the length of the array.

We can enumerate all subsets $i$, where $i \in [0, 2^n)$, if the binary representation of subset $i$ has $m$ ones, and the elements in subset $i$ are not repeated, then we can calculate the incompatibility of subset $i$, denoted as $g[i]$, i.e., $g[i]=\max_{j \in i} \{nums[j]\} - \min_{j \in i} \{nums[j]\}$.

Next, we can use dynamic programming to solve.

We define $f[i]$ as the minimum sum of incompatibilities when the current partitioned subset state is $i$. Initially, $f[0]=0$, which means no elements are partitioned into the subset, and the rest $f[i]=+\infty$.

For state $i$, we find all undivided and non-repeated elements, represented by a state $mask$. If the number of elements in state $mask$ is greater than or equal to $m$, then we enumerate all subsets $j$ of $mask$, and satisfy $j \subset mask$, then $f[i \cup j]=\min \{f[i \cup j], f[i]+g[j]\}$.

Finally, if $f[2^n-1]=+\infty$, it means that it cannot be partitioned into $k$ subsets, return $-1$, otherwise return $f[2^n-1]$.

The time complexity is $O(3^n)$, and the space complexity is $O(2^n)$. Here, $n$ is the length of the array.

<!-- tabs:start -->

### **Python3**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@

## Solutions

**Solution 1: Memorization Search**

We design a function $dfs(i, j, x)$ to represent the length of the longest "good" palindrome subsequence ending with character $x$ in the index range $[i, j]$ of string $s$. The answer is $dfs(0, n - 1, 26)$.

The calculation process of the function $dfs(i, j, x)$ is as follows:

- If $i >= j$, then $dfs(i, j, x) = 0$;
- If $s[i] = s[j]$ and $s[i] \neq x$, then $dfs(i, j, x) = dfs(i + 1, j - 1, s[i]) + 2$;
- If $s[i] \neq s[j]$, then $dfs(i, j, x) = max(dfs(i + 1, j, x), dfs(i, j - 1, x))$.

During the process, we can use memorization search to avoid repeated calculations.

The time complexity is $O(n^2 \times C)$. Where $n$ is the length of the string $s$, and $C$ is the size of the character set. In this problem, $C = 26$.

<!-- tabs:start -->

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

回到题目上,判断一个字符串 $w$ 是否由 `allowed` 中的字符组成,就可以转换为:判断 $f(allowed)$ 和 $f(w)$ 进行按位或运算后的结果是否等于 $f(allowed)$。若是,答案加一。

时间复杂度 $O(m)$,空间复杂度 $O(1)$。其中 $m$ 为所有字符串的总长度
时间复杂度 $O(m)$,其中 $m$ 为所有字符串的总长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@

## Solutions

**Solution 1: Hash Table or Array**

A straightforward approach is to use a hash table or array $s$ to record the characters in `allowed`. Then iterate over the `words` array, for each string $w$, determine whether it is composed of characters in `allowed`. If so, increment the answer.

The time complexity is $O(m)$, and the space complexity is $O(C)$. Here, $m$ is the total length of all strings, and $C$ is the size of the character set `allowed`. In this problem, $C \leq 26$.

**Solution 2: Bit Manipulation**

We can also use a single integer to represent the occurrence of characters in each string. In this integer, each bit in the binary representation indicates whether a character appears.

We simply define a function $f(w)$ that can convert a string $w$ into an integer. Each bit in the binary representation of the integer indicates whether a character appears. For example, the string `ab` can be converted into the integer $3$, which is represented in binary as $11$. The string `abd` can be converted into the integer $11$, which is represented in binary as $1011$.

Back to the problem, to determine whether a string $w$ is composed of characters in `allowed`, we can check whether the result of the bitwise OR operation between $f(allowed)$ and $f(w)$ is equal to $f(allowed)$. If so, increment the answer.

The time complexity is $O(m)$, where $m$ is the total length of all strings. The space complexity is $O(1)$.

<!-- tabs:start -->

### **Python3**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ result[2] = |5-2| + |5-3| + |5-5| = 3 + 2 + 0 = 5。

**方法一:求和 + 枚举**

我们先求出数组 `nums` 所有元素的和,记为 $s$,用变量 $t$ 记录当前已经枚举过的元素之和。
我们先求出数组 $nums$ 所有元素的和,记为 $s$,用变量 $t$ 记录当前已经枚举过的元素之和。

接下来枚举 $nums[i]$,那么 $ans[i] = nums[i] \times i - t + s - t - nums[i] \times (n - i)$,然后我们更新 $t$,即 $t = t + nums[i]$。继续枚举下一个元素,直到枚举完所有元素。

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `nums` 的长度。
时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ result[2] = |5-2| + |5-3| + |5-5| = 3 + 2 + 0 = 5.

## Solutions

**Solution 1: Summation + Enumeration**

First, we calculate the sum of all elements in the array $nums$, denoted as $s$. We use a variable $t$ to record the sum of the elements that have been enumerated so far.

Next, we enumerate $nums[i]$. Then $ans[i] = nums[i] \times i - t + s - t - nums[i] \times (n - i)$. After that, we update $t$, i.e., $t = t + nums[i]$. We continue to enumerate the next element until all elements are enumerated.

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

<!-- tabs:start -->

### **Python3**
Expand Down
2 changes: 1 addition & 1 deletion solution/1600-1699/1686.Stone Game VI/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Bob 会获胜。

选取石头的最优化的策略是,让自己得分最高,同时让对手失分最多。因此,我们创建一个数组 `arr`,其中 `arr[i] = aliceValues[i] + bobValues[i]`,然后对 `arr` 进行降序排序。然后,我们从 `arr` 中取出石头,每次取出两个石头,分别给 Alice 和 Bob,直到 `arr` 中没有石头为止。最后,我们比较 Alice 和 Bob 的得分,得分高的人获胜。

时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `aliceValues` 和 `bobValues` 的长度。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `aliceValues` 和 `bobValues` 的长度。

<!-- tabs:start -->

Expand Down
6 changes: 6 additions & 0 deletions solution/1600-1699/1686.Stone Game VI/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ Bob wins.

## Solutions

**Solution 1: Greedy + Sorting**

The optimal strategy for picking stones is to maximize one's own score while making the opponent lose as much as possible. Therefore, we create an array `arr`, where `arr[i] = aliceValues[i] + bobValues[i]`, and then sort `arr` in descending order. Then, we take stones from `arr`, taking two stones each time, one for Alice and one for Bob, until there are no stones left in `arr`. Finally, we compare the scores of Alice and Bob, and the person with the higher score wins.

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

<!-- tabs:start -->

### **Python3**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func boxDelivering(boxes [][]int, portsCount int, maxBoxes int, maxWeight int) i
本题数据规模达到 $10^5$,而以上代码的时间复杂度为 $O(n^2)$,会超出时间限制。我们仔细观察:

$$
f[i] = min(f[i], f[j] + cs[i - 1] - cs[j] + 2)
f[i] = \min(f[i], f[j] + cs[i - 1] - cs[j] + 2)
$$

实际上我们是要在 $[i-maxBoxes,..i-1]$ 这个窗口内找到一个 $j$,使得 $f[j] - cs[j]$ 的值最小,求滑动窗口的最小值,一种常用的做法是使用单调队列,可以在 $O(1)$ 时间内获取到满足条件的最小值。
Expand Down
Loading