0763划分子母区间 Marathon

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

示例:

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

提示:

S的长度在[1, 500]之间。
S只包含小写字母 'a' 到 'z' 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-labels

参考:

python

# 0763.划分字母区间

class Solution:
    def partitionLabels(self, s: str) -> [int]:
        """
        在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。
        可以分为如下两步:
        - 统计每一个字符最后出现的位置
        - 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
        :param S:
        :return:
        """
        hash = [0] * 26
        # 遍历位置
        for i in range(len(s)):
            hash[ord(s[i]) - ord('a')] = i
        res = []
        left = 0
        right = 0
        # 再遍历一遍,找出最远位置下标
        for i in range(len(s)):
            right = max(right, hash[ord(s[i])-ord('a')])
            if i == right:
                res.append(right-left+1)
                left = i + 1
        return res

golang

package greedy

// 贪心
func partitionLabels(s string) []int {
	var res []int
	var marks [26]int
	left, right := 0, 0
	for i, v := range s {
		marks[v - 'a'] = i
	}
	for i, v := range s {
		right = max(right, marks[v - 'a'])
		if i == right {
			res = append(res, right-left+1)
			left = i + 1
		}
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

原文地址:https://www.cnblogs.com/davis12/p/15609687.html