Skip to content

Commit 5d79d9f

Browse files
authored
feat: add solutions to lc problems: No.3346,3347 (doocs#3739)
1 parent 8326e0c commit 5d79d9f

File tree

22 files changed

+712
-64
lines changed

22 files changed

+712
-64
lines changed

solution/1500-1599/1547.Minimum Cost to Cut a Stick/README.md

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,17 @@ tags:
7373

7474
### 方法一:动态规划(区间 DP)
7575

76-
我们可以往切割点数组 $cuts$ 中添加两个元素,分别是 $0$ 和 $n$,表示棍子的两端。然后我们对 $cuts$ 数组进行排序,这样我们就可以将整个棍子切割为若干个区间,每个区间都有两个切割点。不妨设此时 $cuts$ 数组的长度为 $m$。
76+
我们可以往切割点数组 $\textit{cuts}$ 中添加两个元素,分别是 $0$ 和 $n$,表示棍子的两端。然后我们对 $\textit{cuts}$ 数组进行排序,这样我们就可以将整个棍子切割为若干个区间,每个区间都有两个切割点。不妨设此时 $\textit{cuts}$ 数组的长度为 $m$。
7777

78-
接下来,我们定义 $f[i][j]$ 表示切割区间 $[cuts[i],..cuts[j]]$ 的最小成本。
78+
接下来,我们定义 $\textit{f}[i][j]$ 表示切割区间 $[\textit{cuts}[i],..\textit{cuts}[j]]$ 的最小成本。
7979

80-
如果一个区间只有两个切割点,也就是说,我们无需切割这个区间,那么 $f[i][j] = 0$。
80+
如果一个区间只有两个切割点,也就是说,我们无需切割这个区间,那么 $\textit{f}[i][j] = 0$。
8181

82-
否则,我们枚举区间的长度 $l$,其中 $l$ 等于切割点的数量减去 $1$。然后我们枚举区间的左端点 $i$,右端点 $j$ 可以由 $i + l$ 得到。对于每个区间,我们枚举它的切割点 $k$,其中 $i \lt k \lt j$,那么我们可以将区间 $[i, j]$ 切割为 $[i, k]$ 和 $[k, j]$,此时的成本为 $f[i][k] + f[k][j] + cuts[j] - cuts[i]$,我们取所有可能的 $k$ 中的最小值,即为 $f[i][j]$ 的值。
82+
否则,我们枚举区间的长度 $l$,其中 $l$ 等于切割点的数量减去 $1$。然后我们枚举区间的左端点 $i$,右端点 $j$ 可以由 $i + l$ 得到。对于每个区间,我们枚举它的切割点 $k$,其中 $i \lt k \lt j$,那么我们可以将区间 $[i, j]$ 切割为 $[i, k]$ 和 $[k, j]$,此时的成本为 $\textit{f}[i][k] + \textit{f}[k][j] + \textit{cuts}[j] - \textit{cuts}[i]$,我们取所有可能的 $k$ 中的最小值,即为 $\textit{f}[i][j]$ 的值。
8383

84-
最后,我们返回 $f[0][m - 1]$。
84+
最后,我们返回 $\textit{f}[0][m - 1]$。
8585

86-
时间复杂度 $O(m^3)$,空间复杂度 $O(m^2)$。其中 $m$ 为修改后的 $cuts$ 数组的长度。
86+
时间复杂度 $O(m^3)$,空间复杂度 $O(m^2)$。其中 $m$ 为修改后的 $\textit{cuts}$ 数组的长度。
8787

8888
<!-- tabs:start -->
8989

@@ -186,15 +186,15 @@ func minCost(n int, cuts []int) int {
186186

187187
```ts
188188
function minCost(n: number, cuts: number[]): number {
189-
cuts.push(0);
190-
cuts.push(n);
189+
cuts.push(0, n);
191190
cuts.sort((a, b) => a - b);
192191
const m = cuts.length;
193-
const f: number[][] = new Array(m).fill(0).map(() => new Array(m).fill(0));
194-
for (let i = m - 2; i >= 0; --i) {
195-
for (let j = i + 2; j < m; ++j) {
196-
f[i][j] = 1 << 30;
197-
for (let k = i + 1; k < j; ++k) {
192+
const f: number[][] = Array.from({ length: m }, () => Array(m).fill(0));
193+
for (let l = 2; l < m; l++) {
194+
for (let i = 0; i < m - l; i++) {
195+
const j = i + l;
196+
f[i][j] = Infinity;
197+
for (let k = i + 1; k < j; k++) {
198198
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + cuts[j] - cuts[i]);
199199
}
200200
}
@@ -209,7 +209,11 @@ function minCost(n: number, cuts: number[]): number {
209209

210210
<!-- solution:start -->
211211

212-
### 方法二
212+
### 方法二:动态规划(另一种枚举方式)
213+
214+
我们也可以从大到小枚举 $i$,从小到大枚举 $j$,这样可以保证在计算 $f[i][j]$ 时,状态 $f[i][k]$ 和 $f[k][j]$ 都已经被计算过了,其中 $i \lt k \lt j$。
215+
216+
时间复杂度 $O(m^3)$,空间复杂度 $O(m^2)$。其中 $m$ 为修改后的 $\textit{cuts}$ 数组的长度。
213217

214218
<!-- tabs:start -->
215219

@@ -304,6 +308,27 @@ func minCost(n int, cuts []int) int {
304308
}
305309
```
306310

311+
#### TypeScript
312+
313+
```ts
314+
function minCost(n: number, cuts: number[]): number {
315+
cuts.push(0);
316+
cuts.push(n);
317+
cuts.sort((a, b) => a - b);
318+
const m = cuts.length;
319+
const f: number[][] = Array.from({ length: m }, () => Array(m).fill(0));
320+
for (let i = m - 2; i >= 0; --i) {
321+
for (let j = i + 2; j < m; ++j) {
322+
f[i][j] = 1 << 30;
323+
for (let k = i + 1; k < j; ++k) {
324+
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + cuts[j] - cuts[i]);
325+
}
326+
}
327+
}
328+
return f[0][m - 1];
329+
}
330+
```
331+
307332
<!-- tabs:end -->
308333

309334
<!-- solution:end -->

solution/1500-1599/1547.Minimum Cost to Cut a Stick/README_EN.md

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,17 @@ There are much ordering with total cost &lt;= 25, for example, the order [4, 6,
6868

6969
### Solution 1: Dynamic Programming (Interval DP)
7070

71-
We can add two elements to the cut array $cuts$, which are $0$ and $n$, representing the two ends of the stick. Then we sort the $cuts$ array, so that we can cut the entire stick into several intervals, each interval has two cut points. Suppose the length of the $cuts$ array at this time is $m$.
71+
We can add two elements to the array $\textit{cuts}$, namely $0$ and $n$, representing the two ends of the stick. Then we sort the $\textit{cuts}$ array, so we can divide the entire stick into several intervals, each with two cut points. Let the length of the $\textit{cuts}$ array be $m$.
7272

73-
Next, we define $f[i][j]$ to represent the minimum cost of cutting the interval $[cuts[i],..cuts[j]]$.
73+
Next, we define $\textit{f}[i][j]$ to represent the minimum cost to cut the interval $[\textit{cuts}[i], \textit{cuts}[j]]$.
7474

75-
If an interval only has two cut points, that is, we do not need to cut this interval, then $f[i][j] = 0$.
75+
If an interval has only two cut points, meaning we do not need to cut this interval, then $\textit{f}[i][j] = 0$.
7676

77-
Otherwise, we enumerate the length of the interval $l$, where $l$ is the number of cut points minus $1$. Then we enumerate the left endpoint $i$ of the interval, and the right endpoint $j$ can be obtained by $i + l$. For each interval, we enumerate its cut point $k$, where $i \lt k \lt j$, then we can cut the interval $[i, j]$ into $[i, k]$ and $[k, j]$, the cost at this time is $f[i][k] + f[k][j] + cuts[j] - cuts[i]$, we take the minimum value of all possible $k$, which is the value of $f[i][j]$.
77+
Otherwise, we enumerate the length $l$ of the interval, where $l$ is equal to the number of cut points minus $1$. Then we enumerate the left endpoint $i$ of the interval, and the right endpoint $j$ can be obtained by $i + l$. For each interval, we enumerate its cut point $k$, where $i \lt k \lt j$. We can then divide the interval $[i, j]$ into $[i, k]$ and $[k, j]$. The cost at this point is $\textit{f}[i][k] + \textit{f}[k][j] + \textit{cuts}[j] - \textit{cuts}[i]$. We take the minimum value among all possible $k$, which is the value of $\textit{f}[i][j]$.
7878

79-
Finally, we return $f[0][m - 1]$.
79+
Finally, we return $\textit{f}[0][m - 1]$.
8080

81-
The time complexity is $O(m^3)$, and the space complexity is $O(m^2)$. Here, $m$ is the length of the modified $cuts$ array.
81+
The time complexity is $O(m^3)$, and the space complexity is $O(m^2)$. Here, $m$ is the length of the modified $\textit{cuts}$ array.
8282

8383
<!-- tabs:start -->
8484

@@ -181,15 +181,15 @@ func minCost(n int, cuts []int) int {
181181

182182
```ts
183183
function minCost(n: number, cuts: number[]): number {
184-
cuts.push(0);
185-
cuts.push(n);
184+
cuts.push(0, n);
186185
cuts.sort((a, b) => a - b);
187186
const m = cuts.length;
188-
const f: number[][] = new Array(m).fill(0).map(() => new Array(m).fill(0));
189-
for (let i = m - 2; i >= 0; --i) {
190-
for (let j = i + 2; j < m; ++j) {
191-
f[i][j] = 1 << 30;
192-
for (let k = i + 1; k < j; ++k) {
187+
const f: number[][] = Array.from({ length: m }, () => Array(m).fill(0));
188+
for (let l = 2; l < m; l++) {
189+
for (let i = 0; i < m - l; i++) {
190+
const j = i + l;
191+
f[i][j] = Infinity;
192+
for (let k = i + 1; k < j; k++) {
193193
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + cuts[j] - cuts[i]);
194194
}
195195
}
@@ -204,7 +204,11 @@ function minCost(n: number, cuts: number[]): number {
204204

205205
<!-- solution:start -->
206206

207-
### Solution 2
207+
### Solution 2: Dynamic Programming (Another Enumeration Method)
208+
209+
We can also enumerate $i$ from large to small and $j$ from small to large. This ensures that when calculating $f[i][j]$, the states $f[i][k]$ and $f[k][j]$ have already been computed, where $i \lt k \lt j$.
210+
211+
The time complexity is $O(m^3)$, and the space complexity is $O(m^2)$. Here, $m$ is the length of the modified $\textit{cuts}$ array.
208212

209213
<!-- tabs:start -->
210214

@@ -299,6 +303,27 @@ func minCost(n int, cuts []int) int {
299303
}
300304
```
301305

306+
#### TypeScript
307+
308+
```ts
309+
function minCost(n: number, cuts: number[]): number {
310+
cuts.push(0);
311+
cuts.push(n);
312+
cuts.sort((a, b) => a - b);
313+
const m = cuts.length;
314+
const f: number[][] = Array.from({ length: m }, () => Array(m).fill(0));
315+
for (let i = m - 2; i >= 0; --i) {
316+
for (let j = i + 2; j < m; ++j) {
317+
f[i][j] = 1 << 30;
318+
for (let k = i + 1; k < j; ++k) {
319+
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + cuts[j] - cuts[i]);
320+
}
321+
}
322+
}
323+
return f[0][m - 1];
324+
}
325+
```
326+
302327
<!-- tabs:end -->
303328

304329
<!-- solution:end -->

solution/1500-1599/1547.Minimum Cost to Cut a Stick/Solution.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
function minCost(n: number, cuts: number[]): number {
2-
cuts.push(0);
3-
cuts.push(n);
2+
cuts.push(0, n);
43
cuts.sort((a, b) => a - b);
54
const m = cuts.length;
6-
const f: number[][] = new Array(m).fill(0).map(() => new Array(m).fill(0));
7-
for (let i = m - 2; i >= 0; --i) {
8-
for (let j = i + 2; j < m; ++j) {
9-
f[i][j] = 1 << 30;
10-
for (let k = i + 1; k < j; ++k) {
5+
const f: number[][] = Array.from({ length: m }, () => Array(m).fill(0));
6+
for (let l = 2; l < m; l++) {
7+
for (let i = 0; i < m - l; i++) {
8+
const j = i + l;
9+
f[i][j] = Infinity;
10+
for (let k = i + 1; k < j; k++) {
1111
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + cuts[j] - cuts[i]);
1212
}
1313
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function minCost(n: number, cuts: number[]): number {
2+
cuts.push(0);
3+
cuts.push(n);
4+
cuts.sort((a, b) => a - b);
5+
const m = cuts.length;
6+
const f: number[][] = Array.from({ length: m }, () => Array(m).fill(0));
7+
for (let i = m - 2; i >= 0; --i) {
8+
for (let j = i + 2; j < m; ++j) {
9+
f[i][j] = 1 << 30;
10+
for (let k = i + 1; k < j; ++k) {
11+
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + cuts[j] - cuts[i]);
12+
}
13+
}
14+
}
15+
return f[0][m - 1];
16+
}

solution/3300-3399/3346.Maximum Frequency of an Element After Performing Operations I/README.md

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,25 +86,124 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3346.Ma
8686
#### Python3
8787

8888
```python
89-
89+
class Solution:
90+
def maxFrequency(self, nums: List[int], k: int, numOperations: int) -> int:
91+
cnt = defaultdict(int)
92+
d = defaultdict(int)
93+
for x in nums:
94+
cnt[x] += 1
95+
d[x] += 0
96+
d[x - k] += 1
97+
d[x + k + 1] -= 1
98+
ans = s = 0
99+
for x, t in sorted(d.items()):
100+
s += t
101+
ans = max(ans, min(s, cnt[x] + numOperations))
102+
return ans
90103
```
91104

92105
#### Java
93106

94107
```java
95-
108+
class Solution {
109+
public int maxFrequency(int[] nums, int k, int numOperations) {
110+
Map<Integer, Integer> cnt = new HashMap<>();
111+
TreeMap<Integer, Integer> d = new TreeMap<>();
112+
for (int x : nums) {
113+
cnt.merge(x, 1, Integer::sum);
114+
d.putIfAbsent(x, 0);
115+
d.merge(x - k, 1, Integer::sum);
116+
d.merge(x + k + 1, -1, Integer::sum);
117+
}
118+
int ans = 0, s = 0;
119+
for (var e : d.entrySet()) {
120+
int x = e.getKey(), t = e.getValue();
121+
s += t;
122+
ans = Math.max(ans, Math.min(s, cnt.getOrDefault(x, 0) + numOperations));
123+
}
124+
return ans;
125+
}
126+
}
96127
```
97128

98129
#### C++
99130

100131
```cpp
101-
132+
class Solution {
133+
public:
134+
int maxFrequency(vector<int>& nums, int k, int numOperations) {
135+
unordered_map<int, int> cnt;
136+
map<int, int> d;
137+
138+
for (int x : nums) {
139+
cnt[x]++;
140+
d[x];
141+
d[x - k]++;
142+
d[x + k + 1]--;
143+
}
144+
145+
int ans = 0, s = 0;
146+
for (const auto& [x, t] : d) {
147+
s += t;
148+
ans = max(ans, min(s, cnt[x] + numOperations));
149+
}
150+
151+
return ans;
152+
}
153+
};
102154
```
103155

104156
#### Go
105157

106158
```go
159+
func maxFrequency(nums []int, k int, numOperations int) (ans int) {
160+
cnt := make(map[int]int)
161+
d := make(map[int]int)
162+
for _, x := range nums {
163+
cnt[x]++
164+
d[x] = d[x]
165+
d[x-k]++
166+
d[x+k+1]--
167+
}
168+
169+
s := 0
170+
keys := make([]int, 0, len(d))
171+
for key := range d {
172+
keys = append(keys, key)
173+
}
174+
sort.Ints(keys)
175+
for _, x := range keys {
176+
s += d[x]
177+
ans = max(ans, min(s, cnt[x]+numOperations))
178+
}
179+
180+
return
181+
}
182+
```
107183

184+
#### TypeScript
185+
186+
```ts
187+
function maxFrequency(nums: number[], k: number, numOperations: number): number {
188+
const cnt: Record<number, number> = {};
189+
const d: Record<number, number> = {};
190+
for (const x of nums) {
191+
cnt[x] = (cnt[x] || 0) + 1;
192+
d[x] = d[x] || 0;
193+
d[x - k] = (d[x - k] || 0) + 1;
194+
d[x + k + 1] = (d[x + k + 1] || 0) - 1;
195+
}
196+
let [ans, s] = [0, 0];
197+
const keys = Object.keys(d)
198+
.map(Number)
199+
.sort((a, b) => a - b);
200+
for (const x of keys) {
201+
s += d[x];
202+
ans = Math.max(ans, Math.min(s, (cnt[x] || 0) + numOperations));
203+
}
204+
205+
return ans;
206+
}
108207
```
109208

110209
<!-- tabs:end -->

0 commit comments

Comments
 (0)