動機
看到greedy解後恍然大悟
Problem
You are given a string s
. We want to partition the string into as many parts as possible so that each letter appears in at most one part.
Return a list of integers representing the size of these parts.
Example 1:
Input: s = ababcbacadefegdehijhklijOutput: [9,7,8]Explanation:The partition is ababcbaca, defegde, hijhklij.This is a partition so that each letter appears in at most one part.A partition like ababcbacadefegde, hijhklij is incorrect, because it splits s into less parts.
Example 2:
Input: s = eccbbbbdecOutput: [10]
Constraints:
1 <= s.length <= 500
s
consists of lowercase English letters.
Sol: stack
把每個字元當成一個一個區塊,如果stack中有出現過的字元就做interval merge
class Solution:
def partitionLabels(self, S: str) -> List[int]:
stk = []
for i in range(len(S)):
j = len(stk)-1
while j >= 0 and S[i] not in stk[j][1]:
j -= 1
if j < 0:
stk.append([1,set([S[i]])])
else:
for _ in range(len(stk)-j-1):
tmp = stk.pop()
stk[-1][0] += tmp[0]
stk[-1][1] = stk[-1][1] | tmp[1]
stk[-1][0] += 1
#print(stk,S[:i+1])
return [seg[0] for seg in stk]
Sol2: greedy
如果能知道每個字元的最後位置(hash),就能知道這個區塊的最後位置!!
class Solution(object):
def partitionLabels(self, S):
last = {c: i for i, c in enumerate(S)}
end = start = 0
ans = []
for i, c in enumerate(S):
end = max(end, last[c])
if i == end:
ans.append(i - start + 1)
start = i + 1
return ans