Skip to content

Commit 1d45be1

Browse files
committed
Edit Distance
1 parent 8058083 commit 1d45be1

File tree

5 files changed

+123
-0
lines changed

5 files changed

+123
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
+ [58 Length of Last Word](algorithms/LengthofLastWord)
2626
+ [60 Permutation Sequence(康托展开)](algorithms/PermutationSequence)
2727
+ [65 Valid Number(细节题,状态机)](algorithms/ValidNumber)
28+
+ [72 Edit Distance(DP)](algorithms/EditDistance)
2829
+ [75 Sort Colors](algorithms/SortColors)
2930
+ [100 Same Tree](algorithms/SameTree)
3031
+ [101 Symmetric Tree](algorithms/SymmetricTree)

algorithms/EditDistance/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## Edit Distance
2+
3+
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
4+
5+
You have the following 3 operations permitted on a word:
6+
```
7+
a) Insert a character
8+
b) Delete a character
9+
c) Replace a character
10+
```
11+
12+
## Solution
13+
14+
首先word1变成word2和word2变成word1的步数一样的.
15+
16+
假设需要把s[1..i]变成t[1..j],例如将beauty变成batyu, 所需要的最少的操作数.我们可能有3种可能:
17+
18+
1. 把s[1..i] 转化成t[1..j-1], 设操作次数为case1,我们只需要把t[j]加到后面即可,因此总操作次数为case1 + 1. **添加操作** `比如ab abc`
19+
2. 把s[1..i-1] 转化成t[1..j], 设操作数为case2, 我们只需要把s[i]从后面删除即可,总操作次数为case2 + 1. ** 删除操作 ** `比如abc ab`
20+
3. 如果我们可以把s[1..i-1]转化成t[1..j-1],设操作数为case3,如果s[i] == s[j],总操作数为case3, 否则需要替换一个字符,总操作数为case3 + 1. **替换操作** 比如`abc abe`
21+
22+
我们取这三种情况的最小值作为最后的结果。
23+
24+
我们使用`dp[i][j]`表示s[1..i]转化成t[1..j]的最小操作数。显然:
25+
26+
* `dp[0][j] == j`, 只需要把t全部删除即可
27+
* 同理`dp[i][0] == i`
28+
29+
因此该题转化成dp问题
30+
31+
```c
32+
int minDistance(char *w1, char *w2)
33+
{
34+
const int len1 = strlen(w1);
35+
const int len2 = strlen(w2);
36+
int dp[len1 + 1][len2 + 1];
37+
dp[0][0] = 0;
38+
for (int i = 1; i <= len1; ++i)
39+
dp[i][0] = i;
40+
for (int j = 1; j <= len2; ++j)
41+
dp[0][j] = j;
42+
for (int i = 1; i <= len1; ++i) {
43+
for (int j = 1; j <= len2; ++j) {
44+
int case1 = dp[i - 1][j] + 1;
45+
int case2 = dp[i][j - 1] + 1;
46+
int case3 = dp[i - 1][j - 1] + (w1[i - 1] == w2[j - 1] ? 0 : 1);
47+
dp[i][j] = min3(case1, case2, case3);
48+
}
49+
}
50+
return dp[len1][len2];
51+
}
52+
```

algorithms/EditDistance/in.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
aaa aaa
2+
bab aaa
3+
abcd defg
4+
cccccccccccccc c
5+
c cccccccccccccccc

algorithms/EditDistance/solve.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <stdlib.h>
4+
static inline int min2(int a, int b)
5+
{
6+
return a < b ? a : b;
7+
}
8+
static inline int min3(int a, int b, int c)
9+
{
10+
return min2(min2(a, b), c);
11+
}
12+
int minDistance(char *w1, char *w2)
13+
{
14+
if (w1 == NULL || *w1 == 0) {
15+
if (w2 == NULL || *w2 == 0)
16+
return 0;
17+
else
18+
return strlen(w2);
19+
}
20+
if (w2 == NULL || *w2 == 0)
21+
return strlen(w1);
22+
const int len1 = strlen(w1);
23+
const int len2 = strlen(w2);
24+
int dp[len1 + 1][len2 + 1];
25+
dp[0][0] = 0;
26+
for (int i = 1; i <= len1; ++i)
27+
dp[i][0] = i;
28+
for (int j = 1; j <= len2; ++j)
29+
dp[0][j] = j;
30+
for (int i = 1; i <= len1; ++i) {
31+
for (int j = 1; j <= len2; ++j) {
32+
int case1 = dp[i - 1][j] + 1; // 删除当前字符
33+
int case2 = dp[i][j - 1] + 1;
34+
int case3 = dp[i - 1][j - 1] + (w1[i - 1] == w2[j - 1] ? 0 : 1);
35+
dp[i][j] = min3(case1, case2, case3);
36+
}
37+
}
38+
return dp[len1][len2];
39+
}
40+
int main(int argc, char **argv)
41+
{
42+
char s1[20], s2[20];
43+
while (scanf("%s%s", s1, s2) != EOF) {
44+
printf("|%s, %s| = %d\n",s1, s2, minDistance(s1, s2));
45+
}
46+
return 0;
47+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use leetcode;
2+
drop table if exists Employee;
3+
create table Employee(Id int, Name varchar(20), Salary int, DepartmentId int);
4+
insert into Employee values
5+
(1, "Joe", 70000, 1),
6+
(2, "Henry", 80000, 2),
7+
(3,"Sam", 60000, 2),
8+
(4,"Max", 90000, 1),
9+
(5, "Janet", 69000, 1),
10+
(6, "Randy", 85000, 1);
11+
12+
drop table if exists Department;
13+
create table Department(Id int, Name varchar(20));
14+
insert into Department values
15+
(1,"IT"),
16+
(2,"Sales");
17+
18+
select top(Salary) from Employee group by DepartmentId;

0 commit comments

Comments
 (0)