如何在JavaScript中优雅地将相邻数对拼接成链式数组?
优雅实现整数数对链式结构拼接
给定如下整数数对数组:
let pairs = [ [6, 12], [7, 6], [8, 7], [9, 8], [12, 13], [13, 14], [14, 9] ];
所有数对天然构成链式闭环结构,无需过滤。我们需要将其拼接成连续的链式数组,例如:
let output = [6, 12, 13, 14, 9, 8, 7];
现有暴力解法
let pairs = [ [6, 12], [7, 6], [8, 7], [9, 8], [12, 13], [13, 14], [14, 9] ]; let chain = [pairs[0][0], pairs[0][1]]; pairs.shift(); while(pairs.length !== 1){ let j = null; for(let i = 0; i < pairs.length; i++){ if(pairs[i][0] === chain[chain.length - 1]) { chain.push(pairs[i][1]); j = i; break; } if(pairs[i][1] === chain[chain.length - 1]){ chain.push(pairs[i][0]); j = i; break; } } if(j !== null) { pairs.splice(j, 1); } } console.log(chain);
更优雅的实现方案
通过构建邻接表记录每个节点的连接关系,再从任意起点遍历整个链式结构,逻辑清晰且性能更优:
function buildChain(pairs) { // 构建邻接表,存储每个节点的所有相邻节点 const adjacencyMap = new Map(); pairs.forEach(([a, b]) => { if (!adjacencyMap.has(a)) adjacencyMap.set(a, []); adjacencyMap.get(a).push(b); if (!adjacencyMap.has(b)) adjacencyMap.set(b, []); adjacencyMap.get(b).push(a); }); // 选择第一个数对的第一个元素作为遍历起点 let currentNode = pairs[0][0]; let previousNode = null; const chain = [currentNode]; // 链式结构的节点总数 = 数对数量 + 1 while (chain.length < pairs.length + 1) { // 从当前节点的邻接节点中排除上一个节点,避免往回走 const nextNode = adjacencyMap.get(currentNode).find(node => node !== previousNode); chain.push(nextNode); previousNode = currentNode; currentNode = nextNode; } return chain; } // 测试示例 const pairs = [ [6, 12], [7, 6], [8, 7], [9, 8], [12, 13], [13, 14], [14, 9] ]; console.log(buildChain(pairs)); // 输出: [6, 12, 13, 14, 9, 8, 7]
方案优势
- 性能更优:时间复杂度为O(n),构建邻接表和遍历链均为线性时间,远优于暴力解法的O(n²)
- 逻辑清晰:通过邻接表直接追踪节点连接,避免了嵌套循环和频繁修改原数组(
shift、splice会带来额外性能损耗) - 扩展性强:若后续需要处理多链结构,只需调整起点查找逻辑即可适配
内容的提问来源于stack exchange,提问作者toowren
相关产品推荐
相关产品推荐

