-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0392_is_subsequence.py
More file actions
109 lines (90 loc) · 2.88 KB
/
0392_is_subsequence.py
File metadata and controls
109 lines (90 loc) · 2.88 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
import bisect
import collections
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
if len(s) == 0:
return True
if len(t) == 0:
return False
s_ptr = 0
t_ptr = 0
while t_ptr < len(t):
if s_ptr < len(s) and t[t_ptr] == s[s_ptr]:
s_ptr += 1
t_ptr += 1
return s_ptr == len(s)
class FinalSolution:
def isSubsequence(self, s: str, t: str) -> bool:
# if len(s) == 0:
# return True
# if len(t) == 0:
# return False
# The above edge cases are in the while condition
s_ptr, t_ptr = 0, 0
while t_ptr < len(t) and s_ptr < len(s):
if t[t_ptr] == s[s_ptr]:
s_ptr += 1
t_ptr += 1
# check the s_ptr move to the end.
return s_ptr == len(s)
class BottomUpDPSolution:
def isSubsequence(self, s: str, t: str) -> bool:
n, m = len(s), len(t)
sub_str_table = [[True] * (m + 1)] + [[False] * (m + 1) for _ in range(n)]
for i, s_char in enumerate(s, start=1):
for j, t_char in enumerate(t, start=1):
if s_char == t_char:
sub_str_table[i][j] = sub_str_table[i - 1][j - 1] & True
else:
sub_str_table[i][j] = sub_str_table[i][j - 1]
return sub_str_table[n][m]
class TopDownDPSolution:
def isSubsequence(self, s: str, t: str) -> bool:
n, m = len(s), len(t)
def dp(s_end, t_end):
if s_end < 0:
return True
if t_end < 0:
return False
if s[s_end] == t[t_end]:
return dp(s_end - 1, t_end - 1)
else:
return dp(s_end, t_end - 1)
return dp(n - 1, m - 1)
class HashSolution:
def isSubsequence(self, s: str, t: str) -> bool:
d = collections.defaultdict(list)
for i, c in enumerate(t):
d[c].append(i)
curr = -1
for c in s:
if not c in d:
return False
l = d[c]
p = bisect.bisect_left(l, curr)
if p == len(l):
return False
curr = l[p] + 1
return True
if __name__ == '__main__':
# s, t, expected = 'abc', 'ahbgdc', True
s, t, expected = 'bac', 'ahbgdca', False
# s, t, expected = '', 'abc', True
# s, t, expected = 'abc', '', False
# s, t, expected = 'b', 'efg', False
o = HashSolution().isSubsequence(s, t)
print(o == expected)
# hash of T
# examine sequence order of s from end to start
# complicate than two pointer method
# s = "abc",
# t = "ahbgdc"
# edge cases
# s = '', t = 'abc', True
# s = 'abc', t = '', False
# s = 'a', t='a'
# s= 'ab', t='abca'
# s = 'b', t='efg'
# Two Pointers Solution
# Time: O(|T|)
# Space: O(1)