[路飞]划分字母区间

75 阅读2分钟

记录 1 道算法题

划分字母区间

leetcode-cn.com/problems/pa…


要求:根据字母进行划分,划分出的每一段中,每一段里面相同的同一个字母出现最多。同时划分出尽可能多段。将每一段的长度存到数组里返回。

比如:'ababcbacadefegdehijhklij' 输出:[9,7,8]。

注意的是假设还是上面的字符串,第一段是 'ababcbaca',假如有字母 a 在更后面的地方,'ababcbacadefagdehijhklij',结果就不一样了,所以题目应该是没有这样的设定。

因为可以用贪心的思想,只要得到了每个字母最后出现的位置,那么到这个位置的区域,这个字母都是最多的。但是我们不能保证每一个字母都能够取到他最后出现的位置。贪心的想法就是只要有一个字母取到了他最后出现的位置,那么就进行分段,这一段就是最佳的。

    function partitionLabels(s) {
        // 存放每个字母最后出现的下标
        const z = Array(26)
        // 字母和 a 的 code 值相减就是 0 - 25 的下标
        const offset = 'a'.charCodeAt(0)
        
        // 第一遍循环获取每个字母最后出现的位置
        for(let j = 0; j < s.length; j++) {
            // 字母下标位置
            const i = s[j].charCodeAt(0) - offset
            z[i] = j
        }
        // 第二次循环进行比较,贪取得最后出现的位置的字母
        let start = 0 // 划分的段的开始下标
        let end = 0 // 结束下标
        const res = []
        for(let j = 0; j < s.length; j++) {
            const i = s[j].charCodeAt(0) - offset
            // 计算结束的位置,但有一点,这也许会被最大的数限制。假如一个字母在一头一尾,那么可能只有一段。
            end = Math.max(end, s[i])
            // 最后一次出现就是当前下标
            if (end === j) {
                res.push(end - start + 1) // 长度
                start = end + 1
            }
        }
        
        return res
    }