diff --git a/kt/valid-arrangement-of-pairs.kt b/kt/valid-arrangement-of-pairs.kt new file mode 100644 index 0000000..8fed2a1 --- /dev/null +++ b/kt/valid-arrangement-of-pairs.kt @@ -0,0 +1,56 @@ +class Solution { + private data class Graph( + val neighbors: Map>, + val ingoing: Map, + val outgoing: Map, + ) + + private fun constructGraph(pairs: Array): Graph { + val neighbors = mutableMapOf>() + val ingoing = mutableMapOf() + val outgoing = mutableMapOf() + + pairs.forEach { pair -> + val (left, right) = pair[0] to pair[1] + + neighbors.getOrPut(left) { ArrayDeque() }.add(right) + outgoing[left] = 1 + outgoing.getOrDefault(left, 0) + ingoing[right] = 1 + ingoing.getOrDefault(right, 0) + } + + return Graph(neighbors, ingoing, outgoing) + } + + private fun findStart(g: Graph): Int = + g.outgoing.keys.firstOrNull { + g.outgoing[it] == 1 + g.ingoing.getOrDefault(it, 0) + } ?: g.outgoing.keys.first() + + private fun visit( + g: Graph, + path: MutableList, + u: Int, + ) { + val neighbors = g.neighbors.getOrDefault(u, null) + while (neighbors != null && neighbors.isNotEmpty()) { + val v = neighbors.removeFirst() + visit(g, path, v) + } + + path.add(u) + } + + fun validArrangement(pairs: Array): Array { + val g = constructGraph(pairs) + val start = findStart(g) + + val path = mutableListOf() + visit(g, path, start) + + path.reverse() + + return Array(path.size - 1) { i -> + intArrayOf(path[i], path[i + 1]) + } + } +}