JavaScript函数无法更新变量求助:最大岛屿面积计算返回0
问题分析与修复方案
你的代码返回0的核心原因是JavaScript基本类型的按值传递特性:biggestIslandLength和currentCount都是number类型(基本类型),传递给DFSIslandSearch函数的是它们的副本,函数内部修改的只是副本,完全不会影响主函数中原始变量的值。另外代码里还有硬编码边界判断的问题(固定判断x>4/y>4),应该用矩阵的实际尺寸来适配任意大小的输入。
最优修复:让DFS函数返回当前岛屿的面积
最清晰且符合JS函数设计的方式是让DFS递归函数返回当前岛屿的总面积,主函数拿到这个返回值后直接更新最大值。修改后的代码如下:
function max_area_islands_DFS(matrix) { let biggestIslandLength = 0; const MAX_LENGTH = matrix.length; if (MAX_LENGTH === 0) return 0; // 处理空矩阵边界情况 const MAX_WIDTH = matrix[0].length; for(let x = 0; x < MAX_LENGTH; x++) { for(let y = 0; y < MAX_WIDTH; y++) { // 接收DFS返回的当前岛屿面积,更新最大值 const currentArea = DFSIslandSearch(matrix, x, y, MAX_LENGTH, MAX_WIDTH); biggestIslandLength = Math.max(biggestIslandLength, currentArea); } } return biggestIslandLength; } function DFSIslandSearch(matrix, x, y, maxLen, maxWid) { // 用矩阵实际尺寸判断边界,不再硬编码4 if(x >= maxLen || x < 0 || y >= maxWid || y < 0) { return 0; } if(matrix[x][y] === 0) { return 0; } // 标记为已访问 matrix[x][y] = 0; // 当前格子面积1,加上上下左右四个方向的岛屿面积 return 1 + DFSIslandSearch(matrix, x + 1, y, maxLen, maxWid) + DFSIslandSearch(matrix, x - 1, y, maxLen, maxWid) + DFSIslandSearch(matrix, x, y + 1, maxLen, maxWid) + DFSIslandSearch(matrix, x, y - 1, maxLen, maxWid); } console.log(max_area_islands_DFS([ [1, 1, 1, 0, 0], [0, 1, 0, 0, 1], [0, 0, 1, 1, 0], [0, 1, 1, 0, 0], [0, 0, 1, 0, 0] ])); // 输出5(注:你的预期3有误,测试用例中最大岛屿面积实际为5)
关键修改点:
- DFS返回岛屿面积:递归函数每次返回当前格子(面积1)加上四个方向的岛屿总面积,主函数直接用这个返回值更新最大值,彻底避免了值传递的问题。
- 动态边界判断:用传入的
maxLen和maxWid代替硬编码的4,适配任意大小的矩阵。 - 空矩阵处理:增加空矩阵的边界判断,避免报错。
补充方案:用引用类型传递最大值
如果你坚持要通过传递的方式更新最大值,可以用对象(引用类型)来封装,因为JS中引用类型是按引用传递的,修改对象的属性会影响外部的原始对象:
function max_area_islands_DFS(matrix) { // 用对象封装最大值,对象是引用类型 const result = { biggest: 0 }; const MAX_LENGTH = matrix.length; if (MAX_LENGTH === 0) return 0; const MAX_WIDTH = matrix[0].length; for(let x = 0; x < MAX_LENGTH; x++) { for(let y = 0; y < MAX_WIDTH; y++) { DFSIslandSearch(matrix, x, y, MAX_LENGTH, MAX_WIDTH, result); } } return result.biggest; } function DFSIslandSearch(matrix, x, y, maxLen, maxWid, result) { if(x >= maxLen || x < 0 || y >= maxWid || y < 0) { return 0; } if(matrix[x][y] === 0) { return 0; } matrix[x][y] = 0; const currentArea = 1 + DFSIslandSearch(matrix, x + 1, y, maxLen, maxWid, result) + DFSIslandSearch(matrix, x - 1, y, maxLen, maxWid, result) + DFSIslandSearch(matrix, x, y + 1, maxLen, maxWid, result) + DFSIslandSearch(matrix, x, y - 1, maxLen, maxWid, result); // 修改对象的属性,外部能感知到 result.biggest = Math.max(result.biggest, currentArea); return currentArea; }
为什么这个方案可行?
对象属于引用类型,传递给函数的是对象的引用(内存地址),函数内部修改对象的属性时,操作的是同一个内存地址指向的内容,因此外部的result对象会同步更新。
内容的提问来源于stack exchange,提问作者youngprogrammer1997
相关产品推荐
相关产品推荐

