You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归实现islandPerimeter遇栈溢出及类型错误,求解决方案

问题成因与修复方案

一、RangeError: Maximum call stack size exceeded(调用栈溢出)

成因

递归过程中没有限制重复访问同一陆地单元格,导致无限递归调用,最终超出JavaScript引擎的调用栈容量。比如每次递归都处理同一个grid[i][j] = 1的单元格,没有标记已访问状态,调用栈会持续累积直到触发上限。

修复方法

  • 新增已访问标记:可以直接修改原矩阵,将访问过的陆地单元格从1改为其他值(比如2),确保每个单元格只被递归处理一次;也可以单独维护一个和原矩阵同尺寸的布尔矩阵记录访问状态。
  • 严格控制递归终止条件:当遇到水域或越界情况时立即返回,避免无效递归。

二、TypeError: Cannot read properties of undefined (reading '1')

成因

递归时未先判断坐标是否在矩阵的合法范围内,就直接访问grid[i][j]。比如当i < 0、i >= 总行数、j < 0或j >= 总列数时,grid[i]会是undefined,此时读取grid[i][j]就会抛出该错误。

修复方法

在递归函数的最开头,先检查坐标合法性:如果坐标越界,直接返回1(因为越界的边属于岛屿周长的一部分),再进行后续的单元格值判断。


修复后的示例代码

function islandPerimeter(grid) {
    const rows = grid.length;
    if (rows === 0) return 0;
    const cols = grid[0].length;

    function dfs(i, j) {
        // 先判断坐标是否越界,越界贡献1条周长边
        if (i < 0 || i >= rows || j < 0 || j >= cols) {
            return 1;
        }
        // 遇到水域,贡献1条周长边
        if (grid[i][j] === 0) {
            return 1;
        }
        // 已访问过的陆地,不重复计算
        if (grid[i][j] === 2) {
            return 0;
        }
        // 标记当前陆地为已访问
        grid[i][j] = 2;
        // 递归遍历四个方向,累加周长
        return dfs(i-1, j) + dfs(i+1, j) + dfs(i, j-1) + dfs(i, j+1);
    }

    // 遍历网格找到第一个陆地,启动递归计算
    for (let i = 0; i < rows; i++) {
        for (let j = 0; j < cols; j++) {
            if (grid[i][j] === 1) {
                return dfs(i, j);
            }
        }
    }
    return 0;
}

代码关键点说明

  • 用2标记已访问的陆地,彻底避免重复递归,解决栈溢出问题。
  • 优先判断坐标越界,确保访问grid[i][j]时坐标始终合法,解决undefined读取错误。
  • 越界和水域场景都返回1,因为这两种情况都对应岛屿的一条外围边,直接计入周长。

内容的提问来源于stack exchange,提问作者Gourav Singh Rawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:32:32