劃分字母區(qū)間

2020-06-22 11:44 更新

題目

字符串 S 由小寫(xiě)字母組成。我們要把這個(gè)字符串劃分為盡可能多的片段,同一個(gè)字母只會(huì)出現(xiàn)在其中的一個(gè)片段。返回一個(gè)表示每個(gè)字符串片段的長(zhǎng)度的列表。

示例 1:

輸入:S = "ababcbacadefegdehijhklij" 輸出:[9,7,8] 解釋?zhuān)?劃分結(jié)果為 "ababcbaca", "defegde", "hijhklij"。 每個(gè)字母最多出現(xiàn)在一個(gè)片段中。 像 "ababcbacadefegde", "hijhklij" 的劃分是錯(cuò)誤的,因?yàn)閯澐值钠螖?shù)較少。

提示:

S的長(zhǎng)度在[1, 500]之間。 S只包含小寫(xiě)字母 'a' 到 'z' 。

解題

思路 策略就是不斷地選擇從最左邊起最小的區(qū)間??梢詮牡谝粋€(gè)字母開(kāi)始分析,假設(shè)第一個(gè)字母是 'a',那么第一個(gè)區(qū)間一定包含最后一次出現(xiàn)的 'a'。但第一個(gè)出現(xiàn)的 'a' 和最后一個(gè)出現(xiàn)的 'a' 之間可能還有其他字母,這些字母會(huì)讓區(qū)間變大。舉個(gè)例子,在 "abccaddbeffe" 字符串中,第一個(gè)最小的區(qū)間是 "abccaddb"。 通過(guò)以上的分析,我們可以得出一個(gè)算法:對(duì)于遇到的每一個(gè)字母,去找這個(gè)字母最后一次出現(xiàn)的位置,用來(lái)更新當(dāng)前的最小區(qū)間。 算法 定義數(shù)組 last[char] 來(lái)表示字符 char 最后一次出現(xiàn)的下標(biāo)。定義 anchor 和 j 來(lái)表示當(dāng)前區(qū)間的首尾。如果遇到的字符最后一次出現(xiàn)的位置下標(biāo)大于 j, 就讓 j=last[c] 來(lái)拓展當(dāng)前的區(qū)間。當(dāng)遍歷到了當(dāng)前區(qū)間的末尾時(shí)(即 i==j ),把當(dāng)前區(qū)間加入答案,同時(shí)將 start 設(shè)為 i+1 去找下一個(gè)區(qū)間。

Python



class Solution {
    public List<Integer> partitionLabels(String S) {
        int[] last = new int[26];
        for (int i = 0; i < S.length(); ++i)
            last[S.charAt(i) - 'a'] = i;

        
        int j = 0, anchor = 0;
        List<Integer> ans = new ArrayList();
        for (int i = 0; i < S.length(); ++i) {
            j = Math.max(j, last[S.charAt(i) - 'a']);
            if (i == j) {
                ans.add(i - anchor + 1);
                anchor = i + 1;
            }
        }
        return ans;
    }
}

Java

class Solution(object):
    def partitionLabels(self, S):
        last = {c: i for i, c in enumerate(S)}
        j = anchor = 0
        ans = []
        for i, c in enumerate(S):
            j = max(j, last[c])
            if i == j:
                ans.append(i - anchor + 1)
                anchor = i + 1

            
        return ans

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)