forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
maximum-number-of-non-overlapping-substrings.py
73 lines (68 loc) · 2.39 KB
/
maximum-number-of-non-overlapping-substrings.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
# Time: O(n)
# space: O(1)
class Solution(object):
def maxNumOfSubstrings(self, s):
"""
:type s: str
:rtype: List[str]
"""
def find_right_from_left(s, first, last, left):
right, i = last[ord(s[left])-ord('a')], left
while i <= right:
if first[ord(s[i])-ord('a')] < left:
return -1
right = max(right, last[ord(s[i])-ord('a')])
i += 1
return right
first, last = [float("inf")]*26, [float("-inf")]*26
for i, c in enumerate(s):
first[ord(c)-ord('a')] = min(first[ord(c)-ord('a')], i)
last[ord(c)-ord('a')] = max(last[ord(c)-ord('a')], i)
result = [""]
right = float("inf")
for left, c in enumerate(s):
if left != first[ord(c)-ord('a')]:
continue
new_right = find_right_from_left(s, first, last, left)
if new_right == -1:
continue
if left > right:
result.append("")
right = new_right
result[-1] = s[left:right+1]
return result
# Time: O(n)
# space: O(1)
class Solution2(object):
def maxNumOfSubstrings(self, s):
"""
:type s: str
:rtype: List[str]
"""
def find_right_from_left(s, first, last, left):
right, i = last[ord(s[left])-ord('a')], left
while i <= right:
if first[ord(s[i])-ord('a')] < left:
return -1
right = max(right, last[ord(s[i])-ord('a')])
i += 1
return right
first, last = [float("inf")]*26, [float("-inf")]*26
for i, c in enumerate(s):
first[ord(c)-ord('a')] = min(first[ord(c)-ord('a')], i)
last[ord(c)-ord('a')] = max(last[ord(c)-ord('a')], i)
intervals = []
for c in xrange(len(first)):
if first[c] == float("inf"):
continue
left, right = first[c], find_right_from_left(s, first, last, first[c])
if right != -1:
intervals.append((right, left))
intervals.sort() # Time: O(26log26)
result, prev = [], -1
for right, left in intervals:
if left <= prev:
continue
result.append(s[left:right+1])
prev = right
return result