在一个由小写字母构成的字符串 s
中,包含由一些连续的相同字符所构成的分组。
例如,在字符串 s = "abbxxxxzyy"
中,就含有 "a"
, "bb"
, "xxxx"
, "z"
和 "yy"
这样的一些分组。
分组可以用区间 [start, end]
表示,其中 start
和 end
分别表示该分组的起始和终止位置的下标。上例中的 "xxxx"
分组用区间表示为 [3,6]
。
我们称所有包含大于或等于三个连续字符的分组为 较大分组 。
找到每一个 较大分组 的区间,按起始位置下标递增顺序排序后,返回结果。
示例 1:
输入:s = "abbxxxxzzy"
输出:[[3,6]]
解释:"xxxx" 是一个起始于 3 且终止于 6 的较大分组
。
示例 2:
输入:s = "abc"
输出:[]
解释:"a","b" 和 "c" 均不是符合要求的较大分组。
示例 3:
输入:s = "abcdddeeeeaabbbcd"
输出:[[3,5],[6,9],[12,14]]
解释:较大分组为 "ddd", "eeee" 和 "bbb"
示例 4:
输入:s = "aba"
输出:[]
提示:
1 <= s.length <= 1000
s
仅含小写英文字母
题目链接:https://leetcode-cn.com/problems/positions-of-large-groups/
思路
题目要找长度>=3的连续子串,用双指针分别定位子串的头和尾即可。
注意:在循环结束后要再判断一次连续子串的长度,以防末尾还有未记录的连续子串。
class Solution {
public:
vector<vector<int>> largeGroupPositions(string s) {
int len = s.size();
vector<vector<int>> res;
if(len<3) return res;
int l = 0, r = 1, cnt = 1;
while(r<len){
if(s[r]==s[l]){
++cnt;
}else{
if(cnt>=3){
res.push_back({l, r-1});
}
l = r;
cnt = 1;
}
++r;
}
if(cnt>=3){
res.push_back({l, len-1});
}
return res;
}
};
优化:实际上左指针和子串长度,是2个等效的变量,只需要一个即可。
class Solution {
public:
vector<vector<int>> largeGroupPositions(string s) {
int len = s.size();
vector<vector<int>> res;
if(len<3) return res;
int cnt = 1;
for(int i=1; i<len; ++i){
if(s[i]==s[i-1]){
++cnt;
}else{
if(cnt>=3){
res.push_back({i-cnt, i-1});
}
cnt = 1;
}
}
if(cnt>=3){
res.push_back({len-cnt, len-1});
}
return res;
}
};
其他非常规思路:正则匹配、位运算,参考https://leetcode-cn.com/problems/positions-of-large-groups/solution/zheng-ze-wei-zhan-3jie-fa-chao-100-by-ma-r0vy/