LeetCode 763劃分字母區間
阿新 • • 發佈:2018-12-16
題目詳情
字串 S
由小寫字母組成。我們要把這個字串劃分為儘可能多的片段,同一個字母只會出現在其中的一個片段。返回一個表示每個字串片段的長度的列表。
示例 1:
輸入: S = "ababcbacadefegdehijhklij" 輸出: [9,7,8] 解釋: 劃分結果為 "ababcbaca", "defegde", "hijhklij"。 每個字母最多出現在一個片段中。 像 "ababcbacadefegde", "hijhklij" 的劃分是錯誤的,因為劃分的片段數較少。
注意:
S
的長度在[1, 500]
之間。S
只包含小寫字母'a'
到'z'
。
題目分析
此題關鍵的想法就是找到能分割的條件, 對S的每個字元進行判斷, 看是否此字元是被分割到另一個字元中。
通過分析題目可以知道, 要求一個字元只能出現在一個字串裡, 這裡可以知道第一個條件:
- 當此字元在前面分割的出現,就不能當做分割點
但是這個條件顯然是不夠的,當出現前面分割的字串沒出現的字元時, 是不是能直接加進去呢? 這是不行的 考慮分割此字串 aaaaabcdaefgh 當判斷b的時候, 首先在前面已經分好的字串aaaaa裡面沒有,符合條件。所以我們把b當做新的分割點。 單著顯然是錯誤的,因為在b後面的字串裡,出現了a, 當我們以b作為分割點的話必定有兩個分割的字串,不符合條件。 所以第二個限制條件:
- 分割點後面不能出現前面一個字串中的字元
綜上條件我們可以得到結果
AC程式碼
class Solution {
public:
vector<int> partitionLabels(string S) {
//分割點前的字串的字元種類 (這裡不用存一個完整的字串,只需要存字串出現的種類就可以)
string contain_char = "";
//前一個字串的長度
int strLen = 0;
//返回的陣列
vector<int> re;
for (int i = 0; i < S.size(); i++) {
//當沒有字串被分割時
if (contain_char.size() == 0) {
contain_char += S[i];
strLen++;
continue;
}
//如果當前字母在原來的字串裡 就加入進去
if (contain_char.find(S[i]) != string::npos) {
strLen++;
} else {
//如果上一個string的包含的字元 在此字母后的string出現
//則說明此字元不是分割的地方, 把此字元加入到string
//而且更新contain_char
bool flag = false;
for (auto singleChar : contain_char) {
//後面有字元
if (S.find(singleChar, i+1) != string::npos) {
flag = true;
}
}
//如果後面有字元 就把當前字元加入到前面的字串裡
if (flag) {
contain_char += S[i];
strLen++;
} else {
contain_char = "";
contain_char += S[i];
re.push_back(strLen);
strLen = 1;
}
}
}
re.push_back(strLen);
return re;
}
};
總結
此題利用貪心演算法是我對每一個S的字元, 在能把這個字元分離的情況下。 對每一個字元進行判斷, 這樣得到的字串的數目應該是最多的