问题场景
最近写 TypeScript 时,需要初始化一个二维数组。比如在实现”矩阵置零”算法时,你可能写过类似这样的代码:
1 | const row = 3; |
这段代码看似合理,但实际上存在一个隐藏的陷阱:所有子数组都是同一个数组的引用!
问题分析
当你使用 new Array(row).fill([]) 时:
[]只被创建一次- 这个空数组的引用被复制到二维数组的每个位置
- 修改
matrix_copy[0][0]会同时影响matrix_copy[1][0],matrix_copy[2][0]等
我首先实现的暴力算法,也就是 O(mn) 的空间复杂度,需要拷贝一个原矩阵。初始化数组都是同一个引用,导致了后续的赋值都错乱,且把 0 都覆盖了,结果最后输出的矩阵中全是 1 😄。
解决方案
方法 1:使用 Array.from
1 | const matrix_copy = Array.from({ length: row }, () => []); |
Array.from会为每个元素执行回调函数- 每次执行
() => []都会创建一个新的空数组
方法 2:使用 map
1 | const matrix_copy = new Array(row).fill(null).map(() => []); |
- 先用
null填充数组 - 然后通过
map为每个元素创建新数组
实际应用
在矩阵算法中,正确的初始化方式应该是:
1 | export const violent = (matrix: number[][]) => { |
总结
在 JavaScript/TypeScript 中初始化二维数组时:
- 避免使用
fill([]),因为它会共享引用 - 推荐使用
Array.from或map方法 - 确保每个子数组都是独立的新实例