贪心算法,首先标记每个字符最左最右的位置。然后设置查找函数,基于当前给定位置字符只往后首先,标记各个字符最左最右的位置,设置函数,查找基于给定位置的字符,只往右侧扩展可以到达的字符位置。然后开始遍历字符,每当基于for循环给定的字符,往后查找到一个有效的子串,对比其开始位置是否大于前一个有效子串的最后一个字符的位置,大于则加入新串,不大于则跟新最后一个有效子串为当前找到的新子串,为什么呢?因为新的子串的结束位置一定比上一个发现的子串的位置结束位置要靠前(举例“adefaddaccc”,假设前一个子串开始于i结束在j位置,后一个子串开始位置i+1,结束位置j+k,那么忧郁i到j包含了i+1位置到j的字符种类,于是前一个字符不可能只停在j位置,必然扩展到j+k位置),我们就有了更多的未被加入res的字符在后面可以被用于发觉新的子串。
class Solution:
def maxNumOfSubstrings(self, s: str) -> List[str]:
res = []
leftmost = collections.defaultdict(lambda:float('inf'))
rightmost = collections.defaultdict(lambda:float('-inf'))
for index, char in enumerate(s):
leftmost[char] = min(leftmost[char], index)
rightmost[char] = max(rightmost[char], index)
def findtheend(i):
j = i
curend = rightmost[s[i]]
while j < curend:
if i > leftmost[s[j]]:
return -1
else:
curend = max(curend, rightmost[s[j]])
j += 1
return j
lastend = -1
for start, char in enumerate(s):
if start != leftmost[char]:
continue
curend = findtheend(start)
if curend == -1:
continue
if start > lastend:
res.append(s[start:curend+1])
else:
res[-1] = s[start:curend+1]
lastend = curend
return res