Skip to content

Commit a4774dc

Browse files
committed
feat(leetcode): 2097 Valid Arrangement of Pairs
1 parent ac0a69f commit a4774dc

File tree

5 files changed

+230
-0
lines changed

5 files changed

+230
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
## [2097. Valid Arrangement of Pairs](https://leetcode.com/problems/valid-arrangement-of-pairs/)
2+
<p>You are given a <strong>0-indexed</strong> 2D integer array <code>pairs</code> where <code>pairs[i] = [start<sub>i</sub>, end<sub>i</sub>]</code>. An arrangement of <code>pairs</code> is <strong>valid</strong> if for every index <code>i</code> where <code>1 &lt;= i &lt; pairs.length</code>, we have <code>end<sub>i-1</sub> == start<sub>i</sub></code>.</p>
3+
4+
<p>Return <em><strong>any</strong> valid arrangement of </em><code>pairs</code>.</p>
5+
6+
<p><strong>Note:</strong> The inputs will be generated such that there exists a valid arrangement of <code>pairs</code>.</p>
7+
8+
<p>&nbsp;</p>
9+
<p><strong class="example">Example 1:</strong></p>
10+
11+
<pre>
12+
<strong>Input:</strong> pairs = [[5,1],[4,5],[11,9],[9,4]]
13+
<strong>Output:</strong> [[11,9],[9,4],[4,5],[5,1]]
14+
<strong>Explanation:
15+
</strong>This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
16+
end<sub>0</sub> = 9 == 9 = start<sub>1</sub>
17+
end<sub>1</sub> = 4 == 4 = start<sub>2</sub>
18+
end<sub>2</sub> = 5 == 5 = start<sub>3</sub>
19+
</pre>
20+
21+
<p><strong class="example">Example 2:</strong></p>
22+
23+
<pre>
24+
<strong>Input:</strong> pairs = [[1,3],[3,2],[2,1]]
25+
<strong>Output:</strong> [[1,3],[3,2],[2,1]]
26+
<strong>Explanation:</strong>
27+
This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
28+
end<sub>0</sub> = 3 == 3 = start<sub>1</sub>
29+
end<sub>1</sub> = 2 == 2 = start<sub>2</sub>
30+
The arrangements [[2,1],[1,3],[3,2]] and [[3,2],[2,1],[1,3]] are also valid.
31+
</pre>
32+
33+
<p><strong class="example">Example 3:</strong></p>
34+
35+
<pre>
36+
<strong>Input:</strong> pairs = [[1,2],[1,3],[2,1]]
37+
<strong>Output:</strong> [[1,2],[2,1],[1,3]]
38+
<strong>Explanation:</strong>
39+
This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
40+
end<sub>0</sub> = 2 == 2 = start<sub>1</sub>
41+
end<sub>1</sub> = 1 == 1 = start<sub>2</sub>
42+
</pre>
43+
44+
<p>&nbsp;</p>
45+
<p><strong>Constraints:</strong></p>
46+
47+
<ul>
48+
<li><code>1 &lt;= pairs.length &lt;= 10<sup>5</sup></code></li>
49+
<li><code>pairs[i].length == 2</code></li>
50+
<li><code>0 &lt;= start<sub>i</sub>, end<sub>i</sub> &lt;= 10<sup>9</sup></code></li>
51+
<li><code>start<sub>i</sub> != end<sub>i</sub></code></li>
52+
<li>No two pairs are exactly the same.</li>
53+
<li>There <strong>exists</strong> a valid arrangement of <code>pairs</code>.</li>
54+
</ul>
55+
56+
57+
## Hints
58+
1. Could you convert this into a graph problem?
59+
2. Consider the pairs as edges and each number as a node.
60+
3. We have to find an Eulerian path of this graph. Hierholzer’s algorithm can be used.
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Author: 1chooo<hugo970217@gmail.com>
3+
* Problem: https://leetcode.com/problems/valid-arrangement-of-pairs/
4+
* Runtime: 221ms (99.05%)
5+
*/
6+
7+
const static auto _ = []() {
8+
cin.tie(nullptr)->sync_with_stdio(false);
9+
return nullptr;
10+
}();
11+
12+
class Solution {
13+
public:
14+
vector<vector<int>> validArrangement(vector<vector<int>> &pairs) {
15+
unordered_map<int, vector<int>> adjacencyList;
16+
unordered_map<int, int> inOutDegree;
17+
18+
for (const auto &pair : pairs) {
19+
adjacencyList[pair[0]].push_back(pair[1]);
20+
inOutDegree[pair[0]]++;
21+
inOutDegree[pair[1]]--;
22+
}
23+
24+
// Find starting node
25+
int startNode = pairs[0][0];
26+
for (const auto &[node, degree] : inOutDegree) {
27+
if (degree == 1) {
28+
startNode = node;
29+
break;
30+
}
31+
}
32+
33+
vector<int> path;
34+
stack<int> nodeStack;
35+
nodeStack.push(startNode);
36+
37+
while (!nodeStack.empty()) {
38+
auto &neighbors = adjacencyList[nodeStack.top()];
39+
if (neighbors.empty()) {
40+
path.push_back(nodeStack.top());
41+
nodeStack.pop();
42+
} else {
43+
int nextNode = neighbors.back();
44+
nodeStack.push(nextNode);
45+
neighbors.pop_back();
46+
}
47+
}
48+
49+
vector<vector<int>> arrangement;
50+
int pathSize = path.size();
51+
arrangement.reserve(pathSize - 1);
52+
53+
for (int i = pathSize - 1; i > 0; --i) {
54+
arrangement.push_back({path[i], path[i - 1]});
55+
}
56+
57+
return arrangement;
58+
}
59+
};
60+
61+
/**
62+
* Author: 1chooo<hugo970217@gmail.com>
63+
* Problem: https://leetcode.com/problems/valid-arrangement-of-pairs/
64+
* Runtime: 1430ms (25.24%)
65+
*/
66+
67+
const static auto _ = []() {
68+
cin.tie(nullptr)->sync_with_stdio(false);
69+
return nullptr;
70+
}();
71+
72+
class Solution {
73+
private:
74+
void dfs(vector<int> &path, unordered_map<int, stack<int>> &graph, int start) {
75+
auto &neighbors = graph[start];
76+
while (!neighbors.empty()) {
77+
int next = neighbors.top();
78+
neighbors.pop();
79+
dfs(path, graph, next);
80+
}
81+
path.push_back(start);
82+
}
83+
84+
public:
85+
vector<vector<int>> validArrangement(vector<vector<int>> &pairs) {
86+
unordered_map<int, stack<int>> graph;
87+
unordered_map<int, int> inDegree, outDegree;
88+
89+
for (const auto &pair : pairs) {
90+
int u = pair[0], v = pair[1];
91+
graph[u].push(v);
92+
outDegree[u]++;
93+
inDegree[v]++;
94+
}
95+
96+
int start = pairs[0][0];
97+
for (const auto &[node, _] : graph) {
98+
if (outDegree[node] > inDegree[node]) {
99+
start = node;
100+
break;
101+
}
102+
}
103+
104+
vector<int> path;
105+
dfs(path, graph, start);
106+
reverse(path.begin(), path.end());
107+
108+
vector<vector<int>> result;
109+
for (size_t i = 0; i < path.size() - 1; ++i) {
110+
result.push_back({path[i], path[i + 1]});
111+
}
112+
113+
return result;
114+
}
115+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* Author: 1chooo<hugo970217@gmail.com>
3+
* Problem: https://leetcode.com/problems/valid-arrangement-of-pairs/
4+
* Runtime: ms (%)
5+
*/
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Author: 1chooo<hugo970217@gmail.com>
3+
* Problem: https://leetcode.com/problems/valid-arrangement-of-pairs/
4+
* Runtime: 221ms (99.05%)
5+
*/
6+
7+
class Solution {
8+
public void dfs(List<Integer> pa, Map<Integer, Stack<Integer>> gr, int st) {
9+
Stack<Integer> nei = gr.getOrDefault(st, new Stack<>());
10+
while (!nei.isEmpty()) {
11+
int ne = nei.pop();
12+
dfs(pa, gr, ne);
13+
}
14+
pa.add(st);
15+
}
16+
17+
public int[][] validArrangement(int[][] pairs) {
18+
Map<Integer, Stack<Integer>> gr = new HashMap<>();
19+
Map<Integer, Integer> in = new HashMap<>();
20+
Map<Integer, Integer> out = new HashMap<>();
21+
for (int[] a : pairs) {
22+
int u = a[0], v = a[1];
23+
gr.computeIfAbsent(u, k -> new Stack<>()).push(v);
24+
out.put(u, out.getOrDefault(u, 0) + 1);
25+
in.put(v, in.getOrDefault(v, 0) + 1);
26+
}
27+
int st = pairs[0][0];
28+
for (int k : gr.keySet()) {
29+
if (out.getOrDefault(k, 0) > in.getOrDefault(k, 0)) {
30+
st = k;
31+
break;
32+
}
33+
}
34+
List<Integer> path = new ArrayList<>();
35+
dfs(path, gr, st);
36+
Collections.reverse(path);
37+
int[][] res = new int[pairs.length][2];
38+
for (int i = 0; i < path.size() - 1; i++) {
39+
res[i][0] = path.get(i);
40+
res[i][1] = path.get(i + 1);
41+
}
42+
return res;
43+
}
44+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""
2+
* Author: 1chooo<hugo970217@gmail.com>
3+
* Problem: https://leetcode.com/problems/valid-arrangement-of-pairs/
4+
* Runtime: ms (%)
5+
"""
6+

0 commit comments

Comments
 (0)