较大分组位置

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

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

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

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

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

for循环

python

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def largeGroupPositions(self, s: str) -> List[List[int]]:
res = []
num = 1
for index, i in enumerate(s):
a = s[index + 1] if index + 1 < len(s) else ""
if s[index] == a:
num += 1
else:
if num >= 3:
res.append([index - num + 1, index])
num = 1
return res

go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func largeGroupPositions(s string) [][]int {
num := 1
var res [][]int
for index, i := range s {
var next string
if index + 1 < len(s) {
next = string(s[index + 1])
}
if string(i) == next {
num += 1
} else {
if num >= 3 {
res = append(res, []int{index - num + 1, index})
}
num = 1
}
}
return res
}

时间复杂度:O(n),其中 n 是字符串的长度。我们只需要遍历一次该数组。

空间复杂度:O(1)。我们只需要常数的空间来保存若干变量,注意返回值不计入空间复杂度。

滑动窗口

通过两个指针指向窗口的首端和尾端。
通过尾端的不断确定相同元素,进行窗口尾端向右移动。
如果尾端元素与首端元素不同,则说明达到窗口的最大值,则查看窗口内元素是否达到3,如果达到3则记录。最后将窗口首端直接移动到与尾端相同位置(有KMP记忆的思想)。
当两个指针都达到末端则结束

go

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
func largeGroupPositions(s string) [][]int {
cur, next := 0, 0
var res [][]int
if len(s) <= 2 {
return res
}
for {
if next >= len(s) {
break
}
for {
if next < len(s) {
if s[cur] == s[next] {
next++
} else {
break
}
} else {
break
}
}
if next - cur >= 3 {
res = append(res, []int{cur, next-1})
}
cur = next
}
return res
}