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

递归实现蛇形遍历矩阵遇栈溢出错误,寻求问题排查帮助

蛇形矩阵遍历函数栈溢出问题排查

问题描述

我尝试实现一个函数,接收n×n矩阵(数组的数组),返回按顺时针蛇形遍历后的一维数组。但该代码仅在3×3矩阵下运行正常,矩阵更大时会触发Maximum call stack size exceeded错误。原代码如下:

function snail (array) {
  let result = []
  
  function resultFilling(arrayForResult) {
    if (arrayForResult[0].length === 1) {
      result.push(arrayForResult[0][0])
      return
    }
    
    for (let i = 0; i < arrayForResult.length - 1; i++) {
      result.push(arrayForResult[0][i])
    }
    for (let i = 0; i < arrayForResult.length - 1; i++) {
      result.push(arrayForResult[i][arrayForResult.length - 1])
    }
    for (let i = arrayForResult.length - 1; i > 0; i--) {
      result.push(arrayForResult[arrayForResult.length - 1][i])
    }
    for (let i = arrayForResult.length - 1; i > 0; i--) {
      result.push(arrayForResult[i][0])
    }
    
    let newArr = array.reduce((accum, item, index) => {
      if (index > 0 && index < array.length - 1) {
        accum.push(item.splice(1, item.length - 2))
      }
      return accum
    }, [])
    
    if (newArr.length > 0) resultFilling(newArr)
  }
  
  resultFilling(array)

  return result
}

错误原因分析

  1. 递归依赖原数组而非当前处理数组:构建newArr时用了外层的array变量,而非当前递归接收的arrayForResult。这会导致每次递归生成的子矩阵完全错误,无法正确缩小问题规模,最终触发无限递归,栈溢出。
  2. 修改原数组导致数据破坏:使用splice方法会直接修改原数组的元素,后续递归处理时的数组已经被篡改,逻辑混乱,进一步加剧递归异常。
  3. 边界条件缺失:仅判断了子数组长度为1的情况,没有处理矩阵为空、子数组为空等极端场景,可能导致不必要的递归调用。

修复后的代码

function snail(array) {
  const result = [];

  function resultFilling(currentArr) {
    // 边界判断:当前数组为空或子数组为空时直接返回
    if (!currentArr.length || !currentArr[0].length) return;
    // 处理只剩单个元素的情况
    if (currentArr.length === 1 && currentArr[0].length === 1) {
      result.push(currentArr[0][0]);
      return;
    }

    // 遍历顶部行(除最后一个元素)
    for (let i = 0; i < currentArr[0].length - 1; i++) {
      result.push(currentArr[0][i]);
    }
    // 遍历右侧列(除最后一个元素)
    for (let i = 0; i < currentArr.length - 1; i++) {
      result.push(currentArr[i][currentArr[0].length - 1]);
    }
    // 遍历底部行(反向,除第一个元素)
    for (let i = currentArr[currentArr.length - 1].length - 1; i > 0; i--) {
      result.push(currentArr[currentArr.length - 1][i]);
    }
    // 遍历左侧列(反向,除第一个元素)
    for (let i = currentArr.length - 1; i > 0; i--) {
      result.push(currentArr[i][0]);
    }

    // 生成新的子矩阵:取中间行,每行取中间部分(用slice不修改原数组)
    const newArr = currentArr.slice(1, -1).map(row => row.slice(1, -1));
    
    if (newArr.length > 0) resultFilling(newArr);
  }

  resultFilling(array);
  return result;
}

修改说明

  • 将newArr的构建逻辑改为基于currentArr(当前递归的数组),使用slice方法截取中间行和每行的中间部分,避免修改原数组。
  • 完善边界判断,提前终止无效递归。
  • 统一使用currentArr[0].length来获取列数,适配可能的非方阵(虽然题目要求n×n,但增强鲁棒性)。

内容的提问来源于stack exchange,提问作者skusov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:06:25