830. 较大分组的位置

71 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

题目 leetcode.cn/

  • 在一个由小写字母构成的字符串 s 中,包含由一些连续的相同字符所构成的分组。
  • 例如,在字符串 s = "abbxxxxzyy" 中,就含有 "a""bb""xxxx""z" 和 "yy" 这样的一些分组。
  • 分组可以用区间 [start, end] 表示,其中 start 和 end 分别表示该分组的起始和终止位置的下标。上例中的 "xxxx" 分组用区间表示为 [3,6] 。
  • 我们称所有包含大于或等于三个连续字符的分组为 较大分组 。
  • 找到每一个 较大分组 的区间,按起始位置下标递增顺序排序后,返回结果。

示例

  • 输入:s = "abbxxxxzzy" 输出:[[3,6]];解释 : "xxxx" 是一个起始于 3 且终止于 6 的较大分组。
  • 输入:s = "abc" 输出:[];解释 : "a","b" 和 "c" 均不是符合要求的较大分组。
  • 输入:s = "abcdddeeeeaabbbcd" 输出:[[3,5],[6,9],[12,14]];解释 : 较大分组为 "ddd", "eeee" 和 "bbb"
  • 输入:s = "aba输出:[];解释 : "a"和"b"均不是符合要求的较大分组。

提示

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

代码

function largeGroupPositions(s: string): number[][] {
    if(s.length < 3) return [];
    let result = [];
    for(let i = 0; i < s.length - 1; i++){
        let sum = 1;
        let end = 0;
        for(let j = i + 1; j < s.length; j++){
            if(s[i] !== s[j]){
                break;
            }
            end = j;
            sum += 1;
        }
        if(sum >= 3){
            result.push([i, end]);
            i = i + sum - 1;
        }
    }
    return result;
};

思路

  • 题目要求输出翻译为输出连续个数大于等于3的字符下标区间
    • 首先排除字符串s长度小于3的情况,这种一定是没有满足要求的,直接返回空数组
    • 然后双重遍历整个字符串,判断s[i]s[j]是否为同一个字符
      • 如果不是,退出当前遍历
      • 如果是,需要在外层循环定义一个计数器,用来标记当前字符重复的个数
    • 当每一次内循环结束时,外层循环判断当前字符的重复次数是否大于等于3
      • 如果不是,执行下一次循环
      • 如果是,将当前的起始下标,最后的结束下标添加到结果中
  • 需要在外层循环中定义一个可以保存内层下标的变量,用来保存结束下标
  • 当有符合条件的字符时,添加结果后,外层的遍历i需要及时的调整位置,即当前i加上当前重复字符的次数,然后再减去1,为什么要减去1呢,因为循环的后面做了i++,这里又加了一次,所以要减去这个重复的