数组使用一段连续内存存储元素,因此可以通过下标在 $O(1)$ 时间内访问或修改元素;但在中间插入与删除通常需要移动后续元素,时间复杂度是 $O(n)$。
前缀和:寻找数组中心下标
遍历时维护左侧和,并用总和减去当前元素与左侧和得到右侧和:
def pivot_index(nums):
right = sum(nums)
left = 0
for index, value in enumerate(nums):
right -= value
if left == right:
return index
left += value
return -1
关键是先把当前元素从右侧和中移除,再比较两边。
轮转数组
Python 可以用切片快速表达轮转:
k %= len(nums)
nums[:] = nums[-k:] + nums[:-k]
这里使用 nums[:],是为了修改原列表本身,而不是让局部变量指向一个新列表。若要求 $O(1)$ 额外空间,可以使用“三次反转”:整体反转,再分别反转前 k 个和剩余部分。
旋转矩阵
顺时针旋转方阵可以拆成两步:沿主对角线转置,再左右翻转每一行。把几何变换拆成已有操作,比逐个推导目标下标更不容易出错。
数组题的重点往往不是语法,而是维护清楚循环不变量:每次迭代前后,哪些区间已经处理完成,哪些数据仍然保持原状。