← 返回题目列表

数组题为什么容易出现越界和 off-by-one 错误?

高频 简单 第 5 / 30 题 更新于 2026/07/29
数组越界边界条件下标

简化版

数组下标通常从 0 到 n-1,循环边界、区间开闭和空数组处理稍不统一就会越界或漏元素。写数组题最好固定使用左闭右开 [l, r) 思维,循环用 i < n,并单独检查空数组、单元素、首尾位置。

详细版

off-by-one 是“差 1 位”的边界错误,例如把 i <= n 写成遍历数组,最后会访问 a[n] 越界;或者二分里混用 [l,r][l,r),导致死循环或漏查。

for (int i = 0; i < n; i++) {
  // 合法访问 a[i]
}

面试中不仅要能写对,还要能解释区间含义。推荐把数组区间记成 [start, end),长度就是 end - start,空区间是 start == end,切片和遍历都更统一。

完整版教学

一、数组合法下标是 0 到 n-1

长度为 n 的数组,合法下标不是 1 到 n,而是 0 到 n-1。

n = 5
index: 0 1 2 3 4
value: a b c d e

所以遍历条件通常是 i < n。如果写成 i <= n,最后一次会访问 a[n],越过最后一个元素。

记忆钩子:长度是 n,最后一个下标是 n-1。

二、off-by-one 是差一位的错误

off-by-one 常见于循环、切片、窗口、二分、前缀和。它不一定每次崩溃,有时只是漏掉第一个或最后一个元素。

错误例子:

for (int i = 0; i <= n; i++) {
  sum += a[i]; // i == n 时越界
}

漏元素例子:

for (int i = 1; i < n; i++) {
  sum += a[i]; // 如果没有刻意跳过 a[0],这里漏了首元素
}

面试写代码时,边界错误比思路错误更常见。

三、左闭右开区间更稳定

推荐用 [l, r) 表示区间包含 l,不包含 r。

[0, n) 包含 0..n-1
长度 = n - 0 = n
[l, r) 长度 = r - l
空区间 = l == r

这和很多语言切片一致:

a[start:end] -> 包含 start,不包含 end

当你坚持一种区间模型,循环条件和长度计算会更统一。

四、闭区间也能用,但不能混

二分查找常见两种写法:闭区间 [l, r] 和左闭右开 [l, r)。两者都可以,但更新规则不同。

区间模型初始值循环条件丢弃左半
[l, r]l=0,r=n-1l <= rl = mid + 1
[l, r)l=0,r=nl < rl = mid + 1l = mid 视问题

最危险的是初始用 [l,r],循环又按 [l,r) 更新,结果不是死循环就是漏答案。

五、空数组和单元素是必测样例

很多数组题在正常数据上能跑,空数组或单元素就崩。

[]
[7]
[1, 2]
[2, 1]

例如访问 a[0] 前要确认 n > 0。双指针题中,l < rl <= r 的选择也要用单元素样例验证。

边界样例不只是测试,它能倒逼你确认区间含义。

六、前缀和里的 n+1 也来自边界统一

前缀和常用长度 n+1 的数组:

prefix[0] = 0
prefix[i+1] = prefix[i] + a[i]
sum [l, r) = prefix[r] - prefix[l]

如果 a = [2, 4, 6]

prefix = [0, 2, 6, 12]
sum [1, 3) = prefix[3] - prefix[1] = 12 - 2 = 10

这个设计让空前缀和区间求和都统一,减少特殊分支。

七、常见误区与追问

  • 误区:循环到 i <= n 才能覆盖 n 个元素。 0 基数组覆盖 n 个元素应是 i < n
  • 误区:区间开闭随便写,最后调一下就行。 混用区间模型会导致死循环、漏元素和越界。
  • 误区:空数组不用单独考虑。 访问首元素、尾元素、初始化答案时都可能在空数组崩溃。
  • 追问:为什么推荐 [l,r) 长度是 r-l,空区间是 l==r,和切片、前缀和更统一。
  • 追问:二分为什么容易死循环? 区间含义和边界更新不匹配,mid 没有排除掉。
  • 追问:怎么快速自测边界? 用空数组、单元素、双元素、目标在首尾、不存在这些样例。

八、加强记忆

数组边界题记成“0 到 n-1,区间要统一”。遍历用 i < n,区间尽量用 [l,r),长度就是 r-l,空区间就是 l==r。写完数组题一定拿空数组、单元素、双元素、首尾命中、不存在这 5 类样例过一遍,很多 off-by-one 错误会立刻露出来。