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.html
Example 1:git
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:github
S
will have length in range [1, 500]
.S
will consist of lowercase letters ('a'
to 'z'
) only.
這道題給了咱們一個字符串S,然咱們將其儘量多的分割爲子字符串,條件是每種字符最多隻能出如今一個子串中。好比題目彙總的例子,字符串S中有多個a,這些a必須只能在第一個子串中,再好比全部的字母e值出如今了第二個子串中。那麼這道題的難點就是如何找到字符串的斷點,即拆分紅爲子串的位置。咱們仔細觀察題目中的例子,能夠發現一旦某個字母屢次出現了,那麼其最後一個出現位置必需要在當前子串中,字母a,e,和j,分別是三個子串中的結束字母。因此咱們關注的是每一個字母最後的出現位置,咱們可使用一個 HashMap 來創建字母和其最後出現位置之間的映射,那麼對於題目中的例子來講,咱們能夠獲得以下映射:app
a -> 8
b -> 5
c -> 7
d -> 14
e -> 15
f -> 11
g -> 13
h -> 19
i -> 22
j -> 23
k -> 20
l -> 21less
創建好映射以後,就須要開始遍歷字符串S了,咱們維護一個 start 變量,是當前子串的起始位置,還有一個 last 變量,是當前子串的結束位置,每當咱們遍歷到一個字母,咱們須要在 HashMap 中提取出其最後一個位置,由於一旦當前子串包含了一個字母,其必須包含全部的相同字母,因此咱們要不停的用當前字母的最後一個位置來更新 last 變量,只有當i和 last 相同了,即當 i = 8 時,當前子串包含了全部已出現過的字母的最後一個位置,即以後的字符串裏不會有以前出現過的字母了,此時就應該是斷開的位置,咱們將長度9加入結果 res 中,同理類推,咱們能夠找出以後的斷開的位置,參見代碼以下:post
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 同步地址:this
https://github.com/grandyang/leetcode/issues/763url
相似題目:spa
Merge Intervalscode
參考資料:
https://leetcode.com/problems/partition-labels/