LeetCode 830 Positions of Large Groups 题解:Go 滑动窗口一次遍历求解较大分组区间
LeetCode 830 Positions of Large Groups 题解:Go 滑动窗口一次遍历求解较大分组区间
发布时间:2026/9/12 21:00:29
LeetCode 830 Positions of Large Groups 题解Go 滑动窗口一次遍历求解较大分组区间【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go导读本文围绕 LeetCode 第 830 题「Positions of Large Groups较大分组的位置」展开基于开源仓库 LeetCode-Go 中该题的 题解文档 与其 Go 实现源码 进行讲解。这是一道典型的字符串「连续相同字符分组」问题考察对双指针与滑动窗口思想的应用。读完本文你将掌握如何在一次线性扫描内找出字符串中所有长度不小于 3 的连续字符分组的起止区间理解其时间与空间复杂度并能直接运行仓库中的测试用例进行验证。题目背景与问题定义在一个由小写字母构成的字符串s中连续的相同字符会构成一个个分组group。例如字符串s abbxxxxzyy中依次存在分组a、bb、xxxx、z、yy。每个分组可以用一个闭区间[start, end]表示其中start与end分别是该分组在原字符串中的起始下标与终止下标含端点。上例中的分组xxxx覆盖下标3到6即区间[3, 6]。当一个分组的字符数量大于或等于 3时它被定义为较大分组large group。题目要求返回字符串中所有较大分组的区间并且结果必须按起始下标递增排序。官方示例示例 1Input: s abbxxxxzzy Output: [[3,6]] Explanation: xxxx is the only large group with start index 3 and end index 6.示例 2Input: s abc Output: [] Explanation: We have groups a, b, and c, none of which are large groups.示例 3Input: s abcdddeeeeaabbbcd Output: [[3,5],[6,9],[12,14]] Explanation: The large groups are ddd, eeee, and bbb.示例 4Input: s aba Output: []数据约束1 s.length 1000s仅包含小写英文字母约束决定了实现可以非常轻量字符串最长 1000 个字符即使采用暴力枚举所有子串也能在时限内通过但更优雅的做法是一次线性扫描即仓库题解采用的滑动窗口思路。思路分析双指针与滑动窗口原文档的 解题思路 给出了清晰的算法骨架利用滑动窗口的思想先扩大窗口的右边界找到能到达的相同字母的最右边记录左右边界判断该分组是否满足「长度 ≥ 3」将窗口的左边界移动到上一次右边界的下一位置重复上述过程直至扫完整个字符串。这个过程的本质是双指针扫描用一个end指针负责向前推进并统计连续相同字符用一个start指针记录当前分组的起点。由于字符串从左到右被一次性扫完且end指针只会单调递增每个字符恰好被访问一次因此天然满足题目「按起始下标递增排序」的输出要求——扫描顺序就是下标的递增顺序无需额外排序。该思路在代码层面可以抽象为一个不变量每次外层循环开始时end都指向一个新的、尚未被归入任何分组的字符start end即当前分组的起点。内层循环让end一直向右移动直到字符发生变化或越界此时区间[start, end-1]就是完整的一个分组。源码实现与逐行解读仓库中该题的 Go 实现位于 830. Positions of Large Groups.go核心函数largeGroupPositions如下package leetcode func largeGroupPositions(S string) [][]int { res, end : [][]int{}, 0 for end len(S) { start, str : end, S[end] for end len(S) S[end] str { end } if end-start 3 { res append(res, []int{start, end - 1}) } } return res }逐行解读如下代码说明res, end : [][]int{}, 0res用于收集所有较大分组区间end是窗口右边界指针初始指向下标 0。for end len(S)外层循环只要end未越界就说明还存在尚未扫描的字符可以开启一个新分组。start, str : end, S[end]记录当前分组的起点start并取出当前字符strS[end]返回byte即uint8对纯小写 ASCII 字符做相等比较完全可靠。for end len(S) S[end] str内层循环让end持续右移直到字符变化或到达字符串末尾。循环结束时end指向当前分组最后一个字符的下一个位置。if end-start 3分组长度为end - start注意区间左闭右开。若长度 ≥ 3即为较大分组。res append(res, []int{start, end - 1})题目要求返回闭区间因此终止下标是end - 1。return res结果天然按下标递增排列直接返回。从源码结构可以看出该实现没有引入任何额外数据结构仅依赖两个下标与一个结果切片代码简洁且可读性高非常适合作为「一次遍历统计连续段」的入门模板。复杂度与正确性分析时间复杂度O(n)内层循环中的end指针只会单调右移永远不会回退外层循环本身不消耗额外遍历。因此整个字符串s中的每个字符最多被end访问一次总体时间复杂度为 O(n)其中 n 为s.length本题约束 n ≤ 1000。空间复杂度O(1)不含输出除结果切片res外算法只使用start、end、str等常数个变量。若计入返回结果本身最坏情况如aaaabbbb这类连续多个长度为 4 的分组结果规模为 O(n)。正确性要点分组完备性外层循环每次进入都从「未归类的第一个字符」开始内层循环把连续相同字符一次性全部纳入因此每个字符恰好属于一个分组不重不漏区间计算左闭右开长度end - start与闭区间[start, end-1]严格对应长度判定与输出下标均正确结果有序扫描自左向右进行start单调递增返回结果天然满足题目要求的「按起始下标递增排序」无需额外sort。边界情况与示例推演边界情况单个字符s a分组a长度 1 3返回[]恰好 3 个字符s aaa返回[[0,2]]——长度判定使用而非3 个字符的分组必须被纳入恰好 2 个字符s aa返回[]分组位于字符串末尾s abbb内层循环以end len(S)退出此时end - 1仍为合法下标返回[[1,3]]全串为同一字符s aaaaa返回[[0,4]]整个字符串就是唯一分组。结合官方示例推演以s abcdddeeeeaabbbcd示例 3为例轮次startend扫描后分组长度是否记录101a1否212b1否323c1否436ddd3是[3,5]5610eeee4是[6,9]61012aa2否71215bbb3是[12,14]81517cd2否最终结果[[3,5],[6,9],[12,14]]与官方输出完全一致。仓库中的测试用例与运行方式仓库为该题提供了完整的测试文件 830. Positions of Large Groups_test.go其中以结构体question830组织「参数-期望答案」的用例表覆盖了官方给出的全部四个示例abbxxxxzzy→[[3,6]]abc→ 空结果测试中以[][]int{{}}表示空切片占位abcdddeeeeaabbbcd→[[3,5],[6,9],[12,14]]aba→ 空结果需要说明的是仓库中该题的测试采用打印输出的方式验证结果fmt.Printf输出输入与函数返回并未使用t.Errorf断言这与仓库部分题解测试的「演示型」风格一致读者可对照打印结果人工核对或自行补充断言。在本仓库根目录模块名见 go.mod为github.com/halfrost/LeetCode-GoGo 版本要求 1.19下可通过以下命令运行该题测试# 仅运行本题测试 go test ./leetcode/0830.Positions-of-Large-Groups/ # 运行全部 LeetCode 题解测试 go test ./leetcode/...仓库还提供了覆盖率生成脚本 gotest.sh一条命令即可产出全量覆盖率报告./gotest.sh # 等价于 go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...生成的coverage.txt位于仓库根目录可配合 Codecov 等工具查看全仓库题解的覆盖率统计。小结LeetCode 830「Positions of Large Groups」是一道难度为 Easy 的字符串扫描题但其背后蕴含的双指针/滑动窗口思想在「连续段统计」「区间合并」「字符串分组」等场景中应用广泛。LeetCode-Go 仓库中 largeGroupPositions 的实现以 O(n) 时间、O(1) 额外空间完成了任务以end指针线性推进start记录分组起点用左闭右开长度end - start判断「长度 ≥ 3」输出闭区间[start, end-1]天然有序。掌握这一「一次遍历 连续段判定」的模式可以迁移到 LeetCode 434字符串中的段数、763划分字母区间等同类问题上是刷题与面试中的高频基本功。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考