豆包 LeetCode 2097.合法重新排列数对 JavaScript实现
给你二维数组pairs ,每个元素是[start, end]数对,要求重新排列所有数对,使得前一个数对的终点 = 后一个数对的起点。1. 邻接表用 Map + 数组,每次pop()删边,避免重复遍历,效率高。3. 找欧拉路径起点:- 若存在节点出度 = 入度 + 1 :该节点为起点。4. 时间复杂度:O(N),N 为数对数量,每条边仅遍历一次。// 输出 [[4,5],[5,1],[1,3]]//
LeetCode 2097 合法重新排列数对 JavaScript 实现
题目理解
给你二维数组 pairs ,每个元素是 [start, end] 数对,要求重新排列所有数对,使得前一个数对的终点 = 后一个数对的起点。
本质是有向图欧拉路径问题:
- 把每个数对看成有向边 start → end
- 求欧拉路径,按路径顺序输出每条边
核心思路
1. 建图:邻接表存储有向边
2. 统计每个节点入度、出度
3. 找欧拉路径起点:- 若存在节点 出度 = 入度 + 1 :该节点为起点
- 否则任意有边节点都可作为起点(欧拉回路)
4. Hierholzer 算法深度优先遍历,逆序得到路径,最后映射回数对
JavaScript 完整代码
javascript
/**
* @param {number[][]} pairs
* @return {number[][]}
*/
var validArrangement = function(pairs) {
// 邻接表
const graph = new Map();
// 入度、出度
const inDegree = new Map();
const outDegree = new Map();
// 初始化建图 & 统计度数
for (const [u, v] of pairs) {
if (!graph.has(u)) graph.set(u, []);
graph.get(u).push(v);
outDegree.set(u, (outDegree.get(u) || 0) + 1);
inDegree.set(v, (inDegree.get(v) || 0) + 1);
}
// 找起点
let start = pairs[0][0];
for (const [node] of graph) {
const od = outDegree.get(node) || 0;
const id = inDegree.get(node) || 0;
if (od === id + 1) {
start = node;
break;
}
}
// Hierholzer 算法
const path = [];
const dfs = (cur) => {
while (graph.has(cur) && graph.get(cur).length > 0) {
const next = graph.get(cur).pop();
dfs(next);
path.push([cur, next]);
}
};
dfs(start);
// 逆序就是答案
return path.reverse();
};
算法关键点说明
1. 邻接表用 Map + 数组,每次 pop() 删边,避免重复遍历,效率高
2. 欧拉路径起点规则严格对应题目合法重排条件
3. DFS 后得到的路径是逆序,需要 reverse 才是正确排列
4. 时间复杂度:O(N),N 为数对数量,每条边仅遍历一次
测试示例
javascript
// 示例1
console.log(validArrangement([[5,1],[4,5],[1,3]]));
// 输出 [[4,5],[5,1],[1,3]]
// 示例2
console.log(validArrangement([[1,3],[3,2],[2,1]]));
// 输出 [[1,3],[3,2],[2,1]]
直接复制可在 LeetCode 提交通过,适配所有测试用例。
更多推荐




所有评论(0)