-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
164 lines (142 loc) · 4.99 KB
/
main.py
File metadata and controls
164 lines (142 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Source: https://leetcode.com/problems/edit-distance
# Title: Edit Distance
# Difficulty: Medium
# Author: Mu Yang <http://muyang.pro>
################################################################################################################################
# Given two strings word1 and word2, return the minimum number of operations required to convert word1 to word2.
#
# You have the following three operations permitted on a word:
#
# Insert a character
# Delete a character
# Replace a character
#
# Example 1:
#
# Input: word1 = "horse", word2 = "ros"
# Output: 3
# Explanation:
# horse -> rorse (replace 'h' with 'r')
# rorse -> rose (remove 'r')
# rose -> ros (remove 'e')
#
# Example 2:
#
# Input: word1 = "intention", word2 = "execution"
# Output: 5
# Explanation:
# intention -> inention (remove 't')
# inention -> enention (replace 'i' with 'e')
# enention -> exention (replace 'n' with 'x')
# exention -> exection (replace 'n' with 'c')
# exection -> execution (insert 'u')
#
# Constraints:
#
# 0 <= word1.length, word2.length <= 500
# word1 and word2 consist of lowercase English letters.
#
################################################################################################################################
class Solution:
"""
Needleman–Wunsch algorithm
Time: O(mn); Space: O(m) or O(n)
"""
def minDistance(self, word1: str, word2: str) -> int:
n = len(word1)+1
m = len(word2)+1
if n < m:
n, m = m, n
word1, word2 = word2, word1
# Initialize first row
score = list(range(m))
# Update matrix
for i, c1 in enumerate(word1, 1):
diag = i-1
score[0] = i
for j, c2 in enumerate(word2, 1):
newscore = min(
score[j-1], # Insert
score[j], # Delete
diag - (c1 == c2), # Replace/No Change
) + 1
diag = score[j]
score[j] = newscore
return score[-1]
################################################################################################################################
class Solution1:
"""
Needleman–Wunsch algorithm
Time: O(mn); Space: O(mn)
"""
def minDistance(self, word1: str, word2: str) -> int:
n = len(word1)+1
m = len(word2)+1
# Create empty (n+1)x(m+1) matrix
score = [None]*n
for i in range(n):
score[i] = [0]*m
# Initialize first row and column
score[0][0] = 0
for i in range(1, n):
score[i][0] = i
for j in range(1, m):
score[0][j] = j
# Update matrix
for i, c1 in enumerate(word1, 1):
for j, c2 in enumerate(word2, 1):
score[i][j] = min(
score[i][j-1], # Insert
score[i-1][j], # Delete
score[i-1][j-1] - (c1 == c2), # Replace/No Change
) + 1
return score[-1][-1]
################################################################################################################################
from collections import deque
class Solution2:
"""Find using BFS"""
def minDistance(self, word1: str, word2: str) -> int:
queue = deque([(0, word1,)])
vocab = set(word2)
visited = set()
while True:
ops, word = queue.popleft()
newops = ops+1
visited.add(word)
# Insert 0
for newchar in vocab:
newword = list(word)
newword.insert(0, newchar)
newword = ''.join(newword)
if newword == word2:
return newops
if newword not in visited:
queue.append((newops, newword,))
for i, char in enumerate(word):
# Insert
for newchar in vocab:
newword = list(word)
newword.insert(i+1, newchar)
newword = ''.join(newword)
if newword == word2:
return newops
if newword not in visited:
queue.append((newops, newword,))
# Delete
newword = list(word)
del newword[i]
newword = ''.join(newword)
if newword == word2:
return newops
if newword not in visited:
queue.append((newops, newword,))
# Replace
for newchar in vocab:
if newchar != char:
newword = list(word)
newword[i] = newchar
newword = ''.join(newword)
if newword == word2:
return newops
if newword not in visited:
queue.append((newops, newword,))