[LeetCode] 763. Partition Labels 分割標簽


 

A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.

 

Example 1:

Input: S = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
This is a partition so that each letter appears in at most one part.
A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts.

 

Note:

  1. S will have length in range [1, 500].
  2. S will consist of lowercase letters ('a' to 'z') only.

 

這道題給了我們一個字符串S,然我們將其盡可能多的分割為子字符串,條件是每種字符最多只能出現在一個子串中。比如題目匯總的例子,字符串S中有多個a,這些a必須只能在第一個子串中,再比如所有的字母e值出現在了第二個子串中。那么這道題的難點就是如何找到字符串的斷點,即拆分成為子串的位置。我們仔細觀察題目中的例子,可以發現一旦某個字母多次出現了,那么其最后一個出現位置必須要在當前子串中,字母a,e,和j,分別是三個子串中的結束字母。所以我們關注的是每個字母最后的出現位置,我們可以使用一個 HashMap 來建立字母和其最后出現位置之間的映射,那么對於題目中的例子來說,我們可以得到如下映射:

a -> 8
b -> 5
c -> 7
d -> 14
e -> 15
f -> 11
g -> 13
h -> 19
i -> 22
j -> 23
k -> 20
l -> 21

建立好映射之后,就需要開始遍歷字符串S了,我們維護一個 start 變量,是當前子串的起始位置,還有一個 last 變量,是當前子串的結束位置,每當我們遍歷到一個字母,我們需要在 HashMap 中提取出其最后一個位置,因為一旦當前子串包含了一個字母,其必須包含所有的相同字母,所以我們要不停的用當前字母的最后一個位置來更新 last 變量,只有當i和 last 相同了,即當 i = 8 時,當前子串包含了所有已出現過的字母的最后一個位置,即之后的字符串里不會有之前出現過的字母了,此時就應該是斷開的位置,我們將長度9加入結果 res 中,同理類推,我們可以找出之后的斷開的位置,參見代碼如下:

 

class Solution {
public:
    vector<int> partitionLabels(string S) {
        vector<int> res;
        int n = S.size(), start = 0, last = 0;
        unordered_map<char, int> m;
        for (int i = 0; i < n; ++i) m[S[i]] = i;
        for (int i = 0; i < n; ++i) {
            last = max(last, m[S[i]]);
            if (i == last) {
                res.push_back(i - start + 1);
                start = i + 1;
            }
        }
        return res;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/763

 

類似題目:

Merge Intervals

 

參考資料:

https://leetcode.com/problems/partition-labels/

https://leetcode.com/problems/partition-labels/discuss/113259/Java-2-pass-O(n)-time-O(1)-space-extending-end-pointer-solution

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM