力扣 830. 较大分组的位置

题目说明

在一个由小写字母构成的字符串 s 中,包含由一些连续的相同字符所构成的分组。

例如,在字符串 s = “abbxxxxzyy” 中,就含有 “a”, “bb”, “xxxx”, “z”“yy” 这样的一些分组。

分组可以用区间 [start, end] 表示,其中 startend 分别表示该分组的起始和终止位置的下标。上例中的 “xxxx” 分组用区间表示为 [3,6] 。

我们称所有包含大于或等于三个连续字符的分组为 较大分组

找到每一个 较大分组 的区间,按起始位置下标递增顺序排序后,返回结果。

  • 1 <= s.length <= 1000
  • s 仅含小写英文字母

示例

例1

1
2
3
4
输入:s = "abbxxxxzzy"
输出:[[3,6]]

解释:"xxxx" 是一个起始于 3 且终止于 6 的较大分组。

例2

1
2
3
4
输入:s = "abc"
输出:[]

解释:"a","b" 和 "c" 均不是符合要求的较大分组。

例3

1
2
3
4
输入:s = "abcdddeeeeaabbbcd"
输出:[[3,5],[6,9],[12,14]]

解释:较大分组为 "ddd", "eeee" 和 "bbb"

笔者理解

此题是一道字符串判定算法问题,在力扣题库中被定义为简单题。

解法

当笔者阅读完此题后,发现此题比较直接,“只需依次求出各个位置元素在紧随的后面出现的次数并判断”,此题中的字符串又只存在小写字母,所以我们可以依次把字符串中所有元素遍历并记录下来,再存入次数大于等于三的起始位置和终止位置即可,就让我们看看具体如何实现吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public List<List<Integer>> largeGroupPositions(String s) {
List<List<Integer>> result = new ArrayList<>();
//定义result的结果集
if(s.length()<3){
//如果字符串长度小于3,必定不符合要求
return result;
}
char[] ch = s.toCharArray();
//转化为字节数组方便操作
char temp = ch[0];
//记录上一个字节
int times = 1;
//当前字节出现的次数
int tick = 0;
//记录当前重复字符的下标
for (int i=1;i<ch.length;i++){
if(ch[i]==temp){
//字节重复,次数加一
times++;
}
else{
if(times>=3){
//当前字节出现三次及以上
List save = new ArrayList();
save.add(tick);
save.add(tick+times-1);
//起始位置加上移动的距离即为终止位置
result.add(save);
//记录字节区间并存入
}
times = 1;
tick = i;
//次数重置,标志后移
}
temp = ch[i];
//更新暂存字节值
}
if(times>=3){
//预防全序列为同字节的情况
List save = new ArrayList();
save.add(tick);
save.add(tick+times-1);
result.add(save);
}
return result;
}

时间和空间效率都较高,可见此解法比较适合此题;

image.png

总结

本题是今天的每日一题,难度只有简单,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。