使用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
相关产品推荐
相关产品推荐

