-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
equalize-strings-by-adding-or-removing-characters-at-ends.py
85 lines (77 loc) · 2.55 KB
/
equalize-strings-by-adding-or-removing-characters-at-ends.py
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
# Time: O((n + m) * log(min(n, m)))
# Space: O(min(n, m))
# binary search, rolling hash
class Solution(object):
def minOperations(self, initial, target):
"""
:type initial: str
:type target: str
:rtype: int
"""
def binary_search_right(left, right, check):
while left <= right:
mid = left+(right-left)//2
if not check( mid):
right = mid-1
else:
left = mid+1
return right
def rolling_hash(s, l, lookup, check):
MOD, P = 10**9+7, 113
h = 0
pw = pow(P, l-1, MOD)
for i in xrange(len(s)):
h = (h*P+(ord(s[i])-ord('a')))%MOD
if i < l-1:
continue
if not check:
lookup.add(h)
elif h in lookup:
return True
h = (h-(ord(s[i-(l-1)])-ord('a'))*pw)%MOD
return False
def check(l):
lookup = set()
rolling_hash(target, l, lookup, False)
return rolling_hash(initial, l, lookup, True)
if len(initial) < len(target):
initial, target = target, initial
return len(initial)+len(target)-2*binary_search_right(1, min(len(initial), min(target)), check)
# Time: O(n * m)
# Space: O(1)
# dp
class Solution2(object):
def minOperations(self, initial, target):
"""
:type initial: str
:type target: str
:rtype: int
"""
result = 0
for k in xrange(2):
for i in xrange(k, len(initial)):
curr = 0
for j in xrange(min(len(initial)-i, len(target))):
curr = curr+1 if initial[i+j] == target[j] else 0
result = max(result, curr)
initial, target = target, initial
return len(initial)+len(target)-2*result
# Time: O(n * m)
# Space: O(min(n, m))
# dp
class Solution3(object):
def minOperations(self, initial, target):
"""
:type initial: str
:type target: str
:rtype: int
"""
if len(initial) < len(target):
initial, target = target, initial
result = 0
dp = [0]*(len(target)+1)
for i in xrange(len(initial)):
for j in reversed(xrange(len(target))):
dp[j+1] = dp[j]+1 if initial[i] == target[j] else 0
result = max(result, max(dp))
return len(initial)+len(target)-2*result