2097. Valid Arrangement of Pairs
Description
You are given a 0-indexed 2D integer array pairs
where pairs[i] = [starti, endi]
. An arrangement of pairs
is valid if for every index i
where 1 <= i < pairs.length
, we have endi-1 == starti
.
Return any valid arrangement of pairs
.
Note: The inputs will be generated such that there exists a valid arrangement of pairs
.
Example 1:
Input: pairs = [[5,1],[4,5],[11,9],[9,4]] Output: [[11,9],[9,4],[4,5],[5,1]] Explanation: This is a valid arrangement since endi-1 always equals starti. end0 = 9 == 9 = start1 end1 = 4 == 4 = start2 end2 = 5 == 5 = start3
Example 2:
Input: pairs = [[1,3],[3,2],[2,1]] Output: [[1,3],[3,2],[2,1]] Explanation: This is a valid arrangement since endi-1 always equals starti. end0 = 3 == 3 = start1 end1 = 2 == 2 = start2 The arrangements [[2,1],[1,3],[3,2]] and [[3,2],[2,1],[1,3]] are also valid.
Example 3:
Input: pairs = [[1,2],[1,3],[2,1]] Output: [[1,2],[2,1],[1,3]] Explanation: This is a valid arrangement since endi-1 always equals starti. end0 = 2 == 2 = start1 end1 = 1 == 1 = start2
Constraints:
1 <= pairs.length <= 105
pairs[i].length == 2
0 <= starti, endi <= 109
starti != endi
- No two pairs are exactly the same.
- There exists a valid arrangement of
pairs
.
Solutions
Solution: Eulerian path
- Time complexity: O(n)
- Space complexity: O(n)
JavaScript
js
/**
* @param {number[][]} pairs
* @return {number[][]}
*/
const validArrangement = function (pairs) {
const indegreeMap = new Map();
const outdegreeMap = new Map();
const graph = new Map();
const result = [];
const findFirstNode = () => {
for (const node of graph.keys()) {
const inCount = indegreeMap.get(node) ?? 0;
const outCount = outdegreeMap.get(node) ?? 0;
if (inCount - outCount === 1) {
return node;
}
}
return pairs[0][0];
};
for (const [start, end] of pairs) {
if (!graph.has(start)) {
graph.set(start, []);
}
const inCount = indegreeMap.get(start) ?? 0;
const outCount = outdegreeMap.get(end) ?? 0;
graph.get(start).push(end);
indegreeMap.set(start, inCount + 1);
outdegreeMap.set(end, outCount + 1);
}
const firstNode = findFirstNode();
const euler = node => {
const stack = graph.get(node) ?? [];
while (stack.length) {
const end = stack.pop();
euler(end);
result.push([node, end]);
}
};
euler(firstNode);
return result.reverse();
};