问题描述

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。

示例 1:

输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。

提示:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-labels
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


解题思路

关于合并区间,请参考:http://timd.cn/leetcode/merge-intervals/

先通过一次遍历,得到每个字符的(起始索引、终止索引),然后将问题转化为合并区间。


Python 实现

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: List[List[int]]
        """
        if not intervals or len(intervals) == 1:
            return intervals

        intervals.sort()

        ret = []
        current_left = intervals[0][0]
        current_right = intervals[0][1]
        for ind, (left, right) in enumerate(intervals[1:], start=1):
            if left >= current_right:
                current_right = max(right, current_right)
            else:
                ret.append([current_left, current_right])
                current_left = left
                current_right = right
            if ind == len(intervals) - 1:
                ret.append([current_left, current_right])

        return ret

    def partitionLabels(self, S):
        """
        :type S: str
        :rtype: List[int]
        """
        d = {}
        for ind, ch in enumerate(S):
            if ch not in d:
                d[ch] = [ind, ind]
            else:
                d[ch][1] = ind

        intervals = sorted(d.values(), key=lambda t: t)
        ret = []
        for left, right in self.merge(intervals):
            ret.append(right - left + 1)
        return ret