LeetCode K最弱行JS代码中j循环为何用j<=x而非j<x?
《矩阵中战斗力最弱的 K 行》遍历边界逻辑答疑
- 本题为LeetCode简单难度算法题,以下答疑不涉及题目本身的通用解法讨论,仅针对给出的遍历代码中
j <= x的边界条件设计做解释。
测试用二维矩阵样例
[ [1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1], ]
核心疑问
代码中定义y为矩阵总行数、x为矩阵首行长度(即总列数),内层按行遍历的i循环终止条件为符合常规直觉的i < y,但外层按列遍历的j循环终止条件写为j <= x。直觉上列索引范围是0 ~ x-1,j < x才是不会越界的写法,但实际测试j < x的版本无法得到正确结果。
对应完整参考代码如下:
var kWeakestRows = function(M, K) { let y = M.length, x = M[0].length, vis = new Uint8Array(y), ans = [] for (let j = 0; j <= x; j++) for (let i = 0; i < y; i++) { if (!vis[i] && !M[i][j]) ans.push(i), vis[i]++ if (ans.length === K) return ans } };
逻辑解释
这个写法是刻意利用了JS的语言特性和题目矩阵的规则,完全不是笔误:
- 题目给定的矩阵有明确规则:每行的所有1都排在0的前面,行的战斗力数值等于该行1的总个数,1越少战斗力越弱。
- 这段代码的核心思路是按列从左到右扫描:逐列从上到下遍历所有行,第一次在某行的j位置遇到0,就说明这行的1总共有j个,战斗力确定,按扫描顺序加入结果集即可。
- 多出来的
j = x这一轮迭代,专门用来处理全1行的边界情况:比如样例里的最后一行,所有有效列位置(0到x-1)的值都是1,在j从0到x-1的遍历中永远不会触发!M[i][j]的判断条件,永远进不了结果集。当j等于x时,访问M[i][x]属于数组越界,JS会返回undefined,!undefined的布尔值为true,刚好可以把所有还没被标记过的全1行,按行号从小到大的顺序补进结果集,不会漏算。
如果把终止条件改成j < x,所有全1行都不会被识别加入结果,自然无法得到正确输出。
内容的提问来源于stack exchange,提问作者Yujin Dong
相关产品推荐
相关产品推荐

