Skip to content

Commit 60579ab

Browse files
committedJun 17, 2023
feat: add solutions to lc problems: No.0031,0072
* No.0031.Next Permutation * No.0072.Edit Distance
1 parent 3923835 commit 60579ab

File tree

11 files changed

+291
-152
lines changed

11 files changed

+291
-152
lines changed
 

Diff for: ‎solution/0000-0099/0031.Next Permutation/README.md

+26
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,32 @@ public class Solution {
221221
}
222222
```
223223

224+
### **JavaScript**
225+
226+
```js
227+
/**
228+
* @param {number[]} nums
229+
* @return {void} Do not return anything, modify nums in-place instead.
230+
*/
231+
var nextPermutation = function (nums) {
232+
const n = nums.length;
233+
let i = n - 2;
234+
while (i >= 0 && nums[i] >= nums[i + 1]) {
235+
--i;
236+
}
237+
if (i >= 0) {
238+
let j = n - 1;
239+
while (j > i && nums[j] <= nums[i]) {
240+
--j;
241+
}
242+
[nums[i], nums[j]] = [nums[j], nums[i]];
243+
}
244+
for (i = i + 1, j = n - 1; i < j; ++i, --j) {
245+
[nums[i], nums[j]] = [nums[j], nums[i]];
246+
}
247+
};
248+
```
249+
224250
### **...**
225251

226252
```

Diff for: ‎solution/0000-0099/0031.Next Permutation/README_EN.md

+26
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,32 @@ public class Solution {
211211
}
212212
```
213213

214+
### **JavaScript**
215+
216+
```js
217+
/**
218+
* @param {number[]} nums
219+
* @return {void} Do not return anything, modify nums in-place instead.
220+
*/
221+
var nextPermutation = function (nums) {
222+
const n = nums.length;
223+
let i = n - 2;
224+
while (i >= 0 && nums[i] >= nums[i + 1]) {
225+
--i;
226+
}
227+
if (i >= 0) {
228+
let j = n - 1;
229+
while (j > i && nums[j] <= nums[i]) {
230+
--j;
231+
}
232+
[nums[i], nums[j]] = [nums[j], nums[i]];
233+
}
234+
for (i = i + 1, j = n - 1; i < j; ++i, --j) {
235+
[nums[i], nums[j]] = [nums[j], nums[i]];
236+
}
237+
};
238+
```
239+
214240
### **...**
215241

216242
```

Diff for: ‎solution/0000-0099/0031.Next Permutation/Solution.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {void} Do not return anything, modify nums in-place instead.
4+
*/
5+
var nextPermutation = function (nums) {
6+
const n = nums.length;
7+
let i = n - 2;
8+
while (i >= 0 && nums[i] >= nums[i + 1]) {
9+
--i;
10+
}
11+
if (i >= 0) {
12+
let j = n - 1;
13+
while (j > i && nums[j] <= nums[i]) {
14+
--j;
15+
}
16+
[nums[i], nums[j]] = [nums[j], nums[i]];
17+
}
18+
for (i = i + 1, j = n - 1; i < j; ++i, --j) {
19+
[nums[i], nums[j]] = [nums[j], nums[i]];
20+
}
21+
};

Diff for: ‎solution/0000-0099/0072.Edit Distance/README.md

+75-46
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,29 @@ exection -&gt; execution (插入 'u')
5555

5656
<!-- 这里可写通用的实现逻辑 -->
5757

58-
动态规划
58+
**方法一:动态规划**
5959

60-
`dp[i][j]` 表示将 word1 前 i 个字符组成的字符串 `word1[0...i-1]` 转换成 word2 前 j 个字符组成的字符串 `word2[0...j-1]` 的最小操作次数。m, n 分别表示 word1, word2 的长度
60+
我们定义 $f[i][j]$ 表示将 $word1$ 的前 $i$ 个字符转换成 $word2$ 的前 $j$ 个字符所使用的最少操作数。初始时 $f[i][0] = i$, f[0][j] = j$。其中 $i \in [1, m], j \in [0, n]$
6161

62-
初始化 `dp[i][0] = i``i∈[0, m]`),`dp[0][j] = j``j∈[0, m]`)。
62+
考虑 $f[i][j]$:
6363

64-
i, j 分别从 1 开始遍历,判断 `word1[i - 1]``word2[j - 1]` 是否相等:
64+
- 如果 $word1[i - 1] = word2[j - 1]$,那么我们只需要考虑将 $word1$ 的前 $i - 1$ 个字符转换成 $word2$ 的前 $j - 1$ 个字符所使用的最少操作数,因此 $f[i][j] = f[i - 1][j - 1]$;
65+
- 否则,我们可以考虑插入、删除、替换操作,那么 $f[i][j] = \min(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]) + 1$。
6566

66-
-`word1[i - 1] == word2[j - 1]`,则 `dp[i][j] = dp[i - 1][j - 1]`
67-
-`word1[i - 1] != word2[j - 1]`,则 `dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1`。其中 `dp[i - 1][j] + 1` 对应插入操作,`dp[i][j - 1] + 1` 对应删除操作,`dp[i - 1][j - 1] + 1` 对应替换操作。取三者的最小值即可。
67+
综上,我们可以得到状态转移方程:
6868

69-
递推公式如下:
69+
$$
70+
f[i][j] = \begin{cases}
71+
i, & \text{if } j = 0 \\
72+
j, & \text{if } i = 0 \\
73+
f[i - 1][j - 1], & \text{if } word1[i - 1] = word2[j - 1] \\
74+
\min(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]) + 1, & \text{otherwise}
75+
\end{cases}
76+
$$
7077

71-
![](https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/0000-0099/0072.Edit%20Distance/images/gif.gif)
78+
最后,我们返回 $f[m][n]$ 即可。
7279

73-
最后返回 `dp[m][n]` 即可
80+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是 $word1$ 和 $word2$ 的长度
7481

7582
<!-- tabs:start -->
7683

@@ -82,18 +89,17 @@ i, j 分别从 1 开始遍历,判断 `word1[i - 1]` 与 `word2[j - 1]` 是否
8289
class Solution:
8390
def minDistance(self, word1: str, word2: str) -> int:
8491
m, n = len(word1), len(word2)
85-
dp = [[0] * (n + 1) for _ in range(m + 1)]
86-
for i in range(m + 1):
87-
dp[i][0] = i
88-
for j in range(n + 1):
89-
dp[0][j] = j
90-
for i in range(1, m + 1):
91-
for j in range(1, n + 1):
92-
if word1[i - 1] == word2[j - 1]:
93-
dp[i][j] = dp[i - 1][j - 1]
92+
f = [[0] * (n + 1) for _ in range(m + 1)]
93+
for j in range(1, n + 1):
94+
f[0][j] = j
95+
for i, a in enumerate(word1, 1):
96+
f[i][0] = i
97+
for j, b in enumerate(word2, 1):
98+
if a == b:
99+
f[i][j] = f[i - 1][j - 1]
94100
else:
95-
dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1
96-
return dp[-1][-1]
101+
f[i][j] = min(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]) + 1
102+
return f[m][n]
97103
```
98104

99105
### **Java**
@@ -104,23 +110,21 @@ class Solution:
104110
class Solution {
105111
public int minDistance(String word1, String word2) {
106112
int m = word1.length(), n = word2.length();
107-
int[][] dp = new int[m + 1][n + 1];
108-
for (int i = 0; i <= m; ++i) {
109-
dp[i][0] = i;
110-
}
111-
for (int j = 0; j <= n; ++j) {
112-
dp[0][j] = j;
113+
int[][] f = new int[m + 1][n + 1];
114+
for (int j = 1; j <= n; ++j) {
115+
f[0][j] = j;
113116
}
114117
for (int i = 1; i <= m; ++i) {
118+
f[i][0] = i;
115119
for (int j = 1; j <= n; ++j) {
116120
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
117-
dp[i][j] = dp[i - 1][j - 1];
121+
f[i][j] = f[i - 1][j - 1];
118122
} else {
119-
dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;
123+
f[i][j] = Math.min(f[i - 1][j], Math.min(f[i][j - 1], f[i - 1][j - 1])) + 1;
120124
}
121125
}
122126
}
123-
return dp[m][n];
127+
return f[m][n];
124128
}
125129
}
126130
```
@@ -132,23 +136,21 @@ class Solution {
132136
public:
133137
int minDistance(string word1, string word2) {
134138
int m = word1.size(), n = word2.size();
135-
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
136-
for (int i = 0; i <= m; ++i) {
137-
dp[i][0] = i;
138-
}
139+
int f[m + 1][n + 1];
139140
for (int j = 0; j <= n; ++j) {
140-
dp[0][j] = j;
141+
f[0][j] = j;
141142
}
142143
for (int i = 1; i <= m; ++i) {
144+
f[i][0] = i;
143145
for (int j = 1; j <= n; ++j) {
144146
if (word1[i - 1] == word2[j - 1]) {
145-
dp[i][j] = dp[i - 1][j - 1];
147+
f[i][j] = f[i - 1][j - 1];
146148
} else {
147-
dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
149+
f[i][j] = min({f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]}) + 1;
148150
}
149151
}
150152
}
151-
return dp[m][n];
153+
return f[m][n];
152154
}
153155
};
154156
```
@@ -158,24 +160,24 @@ public:
158160
```go
159161
func minDistance(word1 string, word2 string) int {
160162
m, n := len(word1), len(word2)
161-
dp := make([][]int, m+1)
162-
for i := 0; i <= m; i++ {
163-
dp[i] = make([]int, n+1)
164-
dp[i][0] = i
163+
f := make([][]int, m+1)
164+
for i := range f {
165+
f[i] = make([]int, n+1)
165166
}
166-
for j := 0; j <= n; j++ {
167-
dp[0][j] = j
167+
for j := 1; j <= n; j++ {
168+
f[0][j] = j
168169
}
169170
for i := 1; i <= m; i++ {
171+
f[i][0] = i
170172
for j := 1; j <= n; j++ {
171173
if word1[i-1] == word2[j-1] {
172-
dp[i][j] = dp[i-1][j-1]
174+
f[i][j] = f[i-1][j-1]
173175
} else {
174-
dp[i][j] = min(min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1
176+
f[i][j] = min(f[i-1][j], min(f[i][j-1], f[i-1][j-1])) + 1
175177
}
176178
}
177179
}
178-
return dp[m][n]
180+
return f[m][n]
179181
}
180182
181183
func min(a, b int) int {
@@ -186,6 +188,33 @@ func min(a, b int) int {
186188
}
187189
```
188190

191+
### **TypeScript**
192+
193+
```ts
194+
function minDistance(word1: string, word2: string): number {
195+
const m = word1.length;
196+
const n = word2.length;
197+
const f: number[][] = Array(m + 1)
198+
.fill(0)
199+
.map(() => Array(n + 1).fill(0));
200+
for (let j = 1; j <= n; ++j) {
201+
f[0][j] = j;
202+
}
203+
for (let i = 1; i <= m; ++i) {
204+
f[i][0] = i;
205+
for (let j = 1; j <= n; ++j) {
206+
if (word1[i - 1] === word2[j - 1]) {
207+
f[i][j] = f[i - 1][j - 1];
208+
} else {
209+
f[i][j] =
210+
Math.min(f[i - 1][j], f[i][j - 1], f[i - 1][j - 1]) + 1;
211+
}
212+
}
213+
}
214+
return f[m][n];
215+
}
216+
```
217+
189218
### **...**
190219

191220
```

0 commit comments

Comments
 (0)
Please sign in to comment.