1. 问题描述:
字符串 S
由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
提示:
S
的长度在[1, 500]
之间。S
只包含小写字母'a'
到'z'
。
2. 思路分析:
① 一开始的时候没有啥思路,于是看了一下力扣官方的代码,使用pycharm进行debug调试,发现其中的思路真的好棒,其中使用到了贪心的策略,下面是我自己的一些理解
② 因为同一个字母只能够出现在一个片段中,所以对于当前的字母c,它的切割的位置一定在字母c最后一次出现的位置或者是这个位置更后面的位置,所以我们在一开始的时候就需要遍历字符串计算这些字母最后出现的位置,然后我们再遍历一遍字符串,检查当前字母的位置是否包含了当前位置之前的所有字母最后出现的位置,如果包含了那么在这个位置就可以划分字符串(贪心策略),如何判断是否包含当前位置之前的出现的所有字母呢?我们需要声明一个变量来记录到当前位置字母出现最晚的位置,假如当前遍历的位置恰好等于了当前记录的最晚的位置那么就可以进行划分了,其实画出具体的图会更好理解一点,而且画出图之后更好理解什么时候应该对字符串进行分割
③ 感觉有的时候根据题目的情况画出具体的图例会更有思路
3. 代码如下:
from typing import List
class Solution:
def partitionLabels(self, S: str) -> List[int]:
last = [0] * 26
# 使用enumerate函数可以获取对应的下标与值
for i, c in enumerate(S):
# 记录每一个字符最后一次出现的位置
last[ord(c) - ord("a")] = i
start, end = 0, 0
res = list()
for i, c in enumerate(S):
# 记录到当前位置字母最晚出现的位置
t = last[ord(c) - ord("a")]
end = max(end, t)
if i == end:
res.append(end - start + 1)
start = i + 1
return res