小哆啦解题记 · 数字连续段谜案

📘 题号:228. 汇总区间 - 力扣(LeetCode)

🧪 目标:把一个有序数组拆解成多个最小连续区间段

🛠️ 技术关键词:双指针、去重、边界判断、字符串拼接、时间复杂度分析


第一章:失踪的数字碎片

大雄一脸疑惑地看着一份看似完整的数字清单 [0, 1, 2, 4, 5, 7],问哆啦A梦:

"能不能把它整理成'连续段'?我不想一个一个读!"

哆啦A梦掏出铜锣烧,咀嚼着说:

"你想要的结果是 ['0->2', '4->5', '7'],对吧?"


第二章:初级代码的翻车现场

大雄兴冲冲写下第一版代码:

ini 复制代码
function summaryRanges(nums: number[]): string[] {
    let show = 0
    let count = 0
    let sArr: string[] = []
    for (let fast = 1; fast <= nums.length; fast++) {
        if (nums[show + count] + 1 == nums[fast]) {
            count++
        } else {
            if (count == 0) {
                sArr.push(`${nums[show]}`)
                show += 1
            } else {
                sArr.push(`${nums[show]}->${nums[show + count]}`)
                show += count + 1
                count = 0
            }
        }
    }
    return sArr
}

问题出现了:

  • 😵 如果有重复元素,[1,1,2] 就直接脑震荡
  • 😵 访问 nums[fast] 时,fast == nums.length 会越界
  • 😵 "last + 1 == nums[fast]" 判断不严谨:连续值判断并不意味着"index连续 + 值连续"
  • 😵 逻辑太绕,show + count 维护困难

第三章:Bug排查 + 优化决策

❓ 为什么会出错?

因为你假设了值是连续的,索引也是连续的。但如果数组里有重复或者空洞,比如 [1,1,2,3,7],你就会判断错。

✅ 怎么修?

✅ 方法一:先去重

用 Set 去掉重复值,确保连续性判断不被干扰

✅ 方法二:优化指针与条件

放弃 count,用 start 记录区间起点,i 遍历时动态判断是否到了"连续段的终点"


第四章:优化代码登场(可读性 + 正确性)

typescript 复制代码
function summaryRanges(nums: number[]): string[] {
    if (nums.length === 0) return []

    const result: string[] = []
    const uniqueNums = Array.from(new Set(nums)) // 去重避免重复数字干扰

    let start = uniqueNums[0]

    for (let i = 1; i <= uniqueNums.length; i++) {
        // 到数组尾部 or 当前不连续
        if (i === uniqueNums.length || uniqueNums[i] !== uniqueNums[i - 1] + 1) {
            if (start === uniqueNums[i - 1]) {
                result.push(`${start}`)
            } else {
                result.push(`${start}->${uniqueNums[i - 1]}`)
            }
            // 更新 start 为下一个段的起点
            start = uniqueNums[i]
        }
    }

    return result
}

第五章:为什么要去重?

这点很容易被忽视,但重复数字会让我们误判连续段的"断裂"。

css 复制代码
例子:nums = [1,1,2,3]
去重后:nums = [1,2,3]
连续段 = ['1->3']
不去重时:1 和 1 会被误判为"断裂" -> ['1', '1->3']

第六章:真的 O(n) 吗?

你可能注意到了:

我们用到了 .sort() 吗?没有!

那为啥还能保证区间是"有序"的?因为题目中已明确:输入数组是有序的!

所以我们只做了一次 O(n) 遍历,并用常数空间(Set 和 result)

最终时间复杂度:

  • 去重 + 遍历:O(n)
  • 空间复杂度:O(n) (输出区间)

第七章:小哆啦的记忆卡

技术点 含义
Set 去重 保证连续判断的准确性
双指针(start + i) 跟踪区间头尾
i ≤ len 遍历 + 提前判断断裂 确保每一段被完整结算
输出 a 或 a->b 取决于当前段长度

🧾 技术启示录

  • ✅ 遇到区间合并问题,第一时间想"是否连续 + 是否有重复"
  • ✅ 写循环时注意遍历尾部是否要提前触发逻辑
  • ✅ 条件逻辑简化结构,减少变量依赖,更可维护
  • ✅ 函数要能解释每个逻辑分支"为何而写"

🧨 窗外彩蛋:

胖虎看着自己的 [1,2,2,3,5,6],抱怨道:

"怎么我得到的是 ["1->3","5->6"],不是 ["1->2","2->3","5->6"]?"

哆啦A梦一脸无奈:

"你不去重,就像连续剧中插播广告,剧情不顺你能怪我?"


相关推荐
云淡风轻~窗明几净4 分钟前
角谷猜想最接近严格证明的测试 Version1.1.1
人工智能·算法·机器学习·图论
机器学习之心18 分钟前
PINN × SVM × NSGA-II × 熵权TOPSIS:一套跑通「建模—优化—决策」的多目标优化框架
算法·机器学习·支持向量机
别动我齐刘海1 小时前
机器人 C++ / 系统联调补强2——异常处理、Protobuf
linux·c++·人工智能·学习·算法·机器学习·机器人
荆棘鸟智能2 小时前
短历时洪水预报算法实践:水文模型与 LightGBM 残差订正融合
人工智能·算法·机器人
葫三生2 小时前
关于三生原理系列被技术开发社区批量收录或引发策展边界讨论的一种思考
大数据·人工智能·深度学习·算法·机器学习·数据挖掘·开源
catcatuncle2 小时前
OpenWorkBuddy 部署排错手册:从源码启动到自己搭一个给团队用,七个最容易卡住的地方
算法
avi91112 小时前
【AI教人】在Inspector显示所有Delegate-Odin Inspector之三
java·前端·算法·delegate·inspector·editor扩展·unity editor
淡海水2 小时前
06-02-源码-增量标记算法实现
算法·unity·c#·gc
碧海银沙音频科技研究院3 小时前
实现炬芯ATS308X的usb cdc 串口IAP 固件升级功能实现
人工智能·嵌入式硬件·深度学习·算法
云淡风轻~窗明几净3 小时前
角谷猜想与百度AI的对话dialog(原始稿)
人工智能·算法·机器学习·图论