Hard
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
pairs
.import java.util.LinkedList
import java.util.Queue
@Suppress("NAME_SHADOWING")
class Solution {
fun validArrangement(pairs: Array<IntArray>): Array<IntArray> {
val inOutedge = HashMap<Int, IntArray>()
val adList = getAdList(pairs, inOutedge)
val start = getStart(inOutedge)
val res = Array(pairs.size) { IntArray(2) }
getRes(start, adList, res, pairs.size - 1)
return res
}
private fun getAdList(
pairs: Array<IntArray>,
inOutEdge: HashMap<Int, IntArray>,
): HashMap<Int, Queue<Int>> {
val adList = HashMap<Int, Queue<Int>>()
for (pair in pairs) {
val s = pair[0]
val d = pair[1]
val set = adList.computeIfAbsent(s) { _: Int? -> LinkedList() }
set.add(d)
val sEdgeCnt = inOutEdge.computeIfAbsent(s) { _: Int? -> IntArray(2) }
val dEdgeCnt = inOutEdge.computeIfAbsent(d) { _: Int? -> IntArray(2) }
sEdgeCnt[1]++
dEdgeCnt[0]++
}
return adList
}
private fun getRes(k: Int, adList: HashMap<Int, Queue<Int>>, res: Array<IntArray>, idx: Int): Int {
var idx = idx
val edges = adList[k] ?: return idx
while (edges.isNotEmpty()) {
val edge = edges.poll()
idx = getRes(edge, adList, res, idx)
res[idx--] = intArrayOf(k, edge)
}
return idx
}
private fun getStart(map: HashMap<Int, IntArray>): Int {
var start = -1
for ((k, value) in map) {
val inEdge = value[0]
val outEdge = value[1]
start = k
if (outEdge - inEdge == 1) {
return k
}
}
return start
}
}