问题描述 链接到标题
解题思路 链接到标题
思路一 链接到标题
首先遍历一遍数组,记录每个字母在字符串中出现的最远位置。
声明一个变量right
,用来记录已经遍历的字符中,最远的位置,当遍历到的位置与记录的最远位置重叠时,就说明可以划分数组了。
思路二 链接到标题
首先遍历一遍数组,记录每个字母出现的次数,并记录是否出现;
再遍历一次数组,当第一次碰到该字符时,该字符入栈,最后一次碰到该字符时,弹出栈顶的字符,栈空时,说明可以分割了。
代码 链接到标题
代码一 链接到标题
class Solution {
public:
vector<int> partitionLabels(string S) {
int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置
for (int i = 0; i < S.size(); i++) { // 统计每一个字符最后出现的位置
hash[S[i] - 'a'] = i;
}
vector<int> result;
int left = 0;
int right = 0;
for (int i = 0; i < S.size(); i++) {
right = max(right, hash[S[i] - 'a']); // 找到字符出现的最远边界
if (i == right) {
result.push_back(right - left + 1);
left = i + 1;
}
}
return result;
}
};
代码二 链接到标题
class Solution {
public:
vector<int> partitionLabels(string s) {
vector<int> res;
int arr[26] = {0};
int arr_bool[26] = {0};
int len = 0;
stack<char> st;
for (int i = 0; i < s.size(); i++) {
arr[s[i] - 'a']++;
arr_bool[s[i] - 'a'] = 1;
}
for (int i = 0; i < s.size(); i++) {
len++;
arr[s[i] - 'a']--;
if (arr_bool[s[i] - 'a'] != 0) {
st.push(s[i]);
arr_bool[s[i] - 'a'] = 0;
}
if (arr[s[i] - 'a'] == 0)
st.pop();
if (st.empty()) {
res.push_back(len);
len = 0;
}
}
return res;
}
};