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

使用JavaScript计算矩阵行列式的递归代码运行逻辑求解

矩阵行列式递归实现相关问题解答

1. 按第一行展开的系数求和逻辑

你用到的是行列式的拉普拉斯展开定理,计算逻辑如下:

  • n阶矩阵的行列式值,等于第一行每个元素乘以对应代数余子式的和
  • 代数余子式的计算规则:对于第一行第i列的元素(代码索引起始为0),符号为(-1) ** i(行索引+列索引为0+i,所以幂次为i),后面乘余子式的值
  • 余子式就是删除当前元素所在的第一行、第i列后,剩下的(n-1)阶矩阵的行列式值,也就是你代码里strippedMatrix返回的矩阵的行列式,通过递归调用计算
  • 递归终止条件是矩阵为2阶,直接用公式ad - bc返回结果

2. 为什么修改原矩阵会导致递归失效、需要传副本

JavaScript中数组是引用类型,如果直接把原矩阵传入递归函数,所有层级的递归操作共享的是同一个矩阵对象:

  • 如果你在某层递归中直接修改了这个矩阵(比如调用shift、splice、直接修改元素值等操作),上层递归的循环还没执行完,矩阵的维度、元素就已经被改乱了
  • 改乱后的矩阵很可能永远达不到递归终止条件(比如矩阵长度始终无法降到2),就会出现栈溢出报错
  • 你现在的代码可以正常运行,是因为strippedMatrix函数是遍历原矩阵生成了全新的矩阵返回,没有修改原矩阵,所以不会出现冲突。但如果后续逻辑要修改传入的矩阵,就必须先做深拷贝生成独立副本再操作,避免互相影响。

3. 现有代码的小优化点

你当前代码里let copyMat = matrix的写法并没有生成真正的副本,只是把原矩阵的引用赋值给了copyMat,两个变量指向的还是同一个矩阵。如果需要生成独立的二维矩阵副本,可以用如下写法:

let copyMat = matrix.map(row => [...row])

你提供的可运行实现代码如下:

function DeterminantOfMatrix(matrix) {
    let givenMatrix = matrix;
    let validInput = true;

    // 输入校验
    let columnLength = givenMatrix.length;
    givenMatrix.forEach(row => row.length !== columnLength ? validInput = false : false);
    if (!validInput) return "输入合法的n*n矩阵";

    // 按第一行计算行列式
    // strippedMatrix 函数会删除指定的行和列
    function strippedMatrix(matrix, index) {
        if (matrix.length === 2 || matrix.length === 0) return matrix;
        let givenMatrix = matrix;
        let resultMatrix = [];
        // 删除要忽略的行和列
        for (let i = 0; i < givenMatrix.length; i++) {
            let container = [];
            for (let j = 0; j < givenMatrix[i].length; j++) {
                if (j !== index) {
                    container.push(givenMatrix[i][j]);
                }
            }
            resultMatrix.push(container);
        }
        resultMatrix.shift();
        return resultMatrix;
    }

    // 不要修改递归函数的输入
    // 先做拷贝再修改
    function recursiveDeterminantMatrix(matrix) {
        let mat = matrix;
        let copyMat = matrix;
        if (mat.length === 2 && mat[0].length === 2) {
            let result = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
            return result;
        } else {
            // 求和所有代数余子式的值
            let answer = 0;
            for (let i = 0; i < mat.length; i++) {
                let cofactor =
                    (-1) ** i * mat[0][i] * recursiveDeterminantMatrix(strippedMatrix(copyMat, i));
                answer += cofactor;
            }
            return answer;
        }
    }

    return recursiveDeterminantMatrix(givenMatrix);
}


// 测试用例
DeterminantOfMatrix([
    [1, 2, 3, 4],
    [4, 5, 6, 7],
    [8, 9, 6, 7],
    [3, 2, 3, 1],
]); // 返回-12

// DeterminantOfMatrix([
//     [1, 2, 3],
//     [4, 5, 6],
//     [8, 9, 6],
// ]); // 返回12

// DeterminantOfMatrix([
//     [1, 2],
//     [8, 9],
// ]); // 返回-7

内容的提问来源于stack exchange,提问作者sadat-saim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:06:03