数组元素索引与值的最长链查找:递归代码错误排查及单参数函数实现咨询
Fixing Your Port Chain Length Calculation & Single-Parameter Implementation
问题诊断:你的代码哪里错了?
你的递归逻辑存在两个核心问题,导致无法正确计算所有路径:
- 仅处理第一个匹配节点:当多个端口指向当前
index时,你找到第一个匹配项就直接return递归,这会跳过其他分支的计算——比如在测试用例[1,0,-1,2]中,节点0和1形成循环的路径、节点3指向2的路径,你的代码会漏掉部分有效路径的长度统计。 - 分支记录逻辑混乱:
branches数组没有正确收集所有起始节点的路径长度,递归过程中缺少回溯和多分支合并的处理,导致最终无法得到完整的路径数据。
修正后的递归实现(保留你的核心思路)
我们需要修改递归函数,让它遍历所有指向当前节点的端口,完整收集所有分支的路径信息,同时加入循环检测避免无限递归:
function getResult(connections) { const endIndex = connections.findIndex(e => e === -1); // 递归计算所有指向当前节点的路径 function calculatePaths(currentIndex, depth, visited = new Set()) { if (visited.has(currentIndex)) return []; // 遇到循环,跳过无效路径 visited.add(currentIndex); const branches = []; for (let i = 0; i < connections.length; i++) { if (connections[i] === currentIndex) { const subVisited = new Set(visited); // 复制访问集合,避免分支互相干扰 const subBranches = calculatePaths(i, depth + 1, subVisited); if (subBranches.length === 0) { // 当前节点是起始节点,记录索引和路径长度 branches.push([i, depth + 1]); } else { // 合并子分支的结果 branches.push(...subBranches); } } } return branches; } const allPaths = calculatePaths(endIndex, 0); // 按路径长度降序排序,长度相同时按测试用例要求取索引(优先小索引或大索引,根据用例调整) allPaths.sort((a, b) => { if (b[1] !== a[1]) return b[1] - a[1]; return a[0] - b[0]; // 长度相同时取索引较小的,匹配测试用例[2,1,-1]的预期 }); return allPaths[0][0]; }
单参数函数的优雅实现(闭包+记忆化)
当然可以用单参数函数实现!利用闭包访问connections,结合记忆化递归避免重复计算,同时处理循环场景:
function getResult(connections) { const endIndex = connections.findIndex(e => e === -1); const memo = new Array(connections.length).fill(-1); memo[endIndex] = 0; // 终点到自身的路径长度为0 // 计算单个节点到-1的有效路径长度(无效路径标记为-1) const getPathLength = (index, visited = new Set()) => { if (memo[index] !== -1) return memo[index]; if (visited.has(index)) { memo[index] = -1; // 循环路径无法到达终点,标记无效 return -1; } if (connections[index] === -1) { memo[index] = 0; return 0; } visited.add(index); const nextLength = getPathLength(connections[index], visited); memo[index] = nextLength === -1 ? -1 : 1 + nextLength; return memo[index]; }; // 预计算所有节点的路径长度 for (let i = 0; i < connections.length; i++) { getPathLength(i); } // 找到最长有效路径的起始索引 let maxLength = -1; let resultIndex = 0; for (let i = 0; i < connections.length; i++) { if (memo[i] > maxLength || (memo[i] === maxLength && i < resultIndex)) { maxLength = memo[i]; resultIndex = i; } } return resultIndex; }
这个实现高效且符合单参数要求,所有测试用例都能得到正确输出:
console.log(getResult([1, 2, -1])); // 0 ✔️ console.log(getResult([1, -1, 1, 2])); // 3 ✔️ console.log(getResult([2, 1, -1])); // 0 ✔️ console.log(getResult([3, 4, 1, -1, 3])); // 2 ✔️ console.log(getResult([1, 0, -1, 2])); // 3 ✔️ console.log(getResult([3, 2, 1, -1])); // 0 ✔️ console.log(getResult([2, 2, 1, 5, 3, -1, 4, 5, 2, 3])); // 6 ✔️
内容的提问来源于stack exchange,提问作者toy boy
相关产品推荐
相关产品推荐

