Build a Matrix With Conditions

hard topological sort matrix

Problem

You are given a positive integer k and two lists of pairs. Each rowConditions[i] = [a, b] demands that value a end up in a row strictly above value b, and each colConditions[j] = [a, b] demands that a end up in a column strictly to the left of b.

Build any k × k matrix containing each integer from 1 to k exactly once (every other cell holds 0) that satisfies all conditions, or return an empty matrix if the conditions are contradictory.

Inputk = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]]
Output[[0,0,1],[3,0,0],[0,2,0]]
One valid answer: rows hold 1, 3, 2 top-to-bottom and columns hold 3, 2, 1 left-to-right, satisfying every condition.

def build_matrix(k, row_conditions, col_conditions):
    def topo_sort(conds):
        adj = [[] for _ in range(k + 1)]
        indeg = [0] * (k + 1)
        for a, b in conds:
            adj[a].append(b)
            indeg[b] += 1
        queue = [v for v in range(1, k + 1) if indeg[v] == 0]
        order = []
        while queue:
            v = queue.pop(0)
            order.append(v)
            for nxt in adj[v]:
                indeg[nxt] -= 1
                if indeg[nxt] == 0:
                    queue.append(nxt)
        return order if len(order) == k else []

    row_order = topo_sort(row_conditions)
    col_order = topo_sort(col_conditions)
    if not row_order or not col_order:
        return []
    row_idx = {v: i for i, v in enumerate(row_order)}
    col_idx = {v: i for i, v in enumerate(col_order)}
    matrix = [[0] * k for _ in range(k)]
    for v in range(1, k + 1):
        matrix[row_idx[v]][col_idx[v]] = v
    return matrix
function buildMatrix(k, rowConditions, colConditions) {
  const topoSort = (conds) => {
    const adj = Array.from({ length: k + 1 }, () => []);
    const indeg = new Array(k + 1).fill(0);
    for (const [a, b] of conds) { adj[a].push(b); indeg[b]++; }
    const queue = [];
    for (let v = 1; v <= k; v++) if (indeg[v] === 0) queue.push(v);
    const order = [];
    let head = 0;
    while (head < queue.length) {
      const v = queue[head++];
      order.push(v);
      for (const nxt of adj[v])
        if (--indeg[nxt] === 0) queue.push(nxt);
    }
    return order.length === k ? order : [];
  };
  const rowOrder = topoSort(rowConditions);
  const colOrder = topoSort(colConditions);
  if (!rowOrder.length || !colOrder.length) return [];
  const rowIdx = new Map(), colIdx = new Map();
  rowOrder.forEach((v, i) => rowIdx.set(v, i));
  colOrder.forEach((v, i) => colIdx.set(v, i));
  const matrix = Array.from({ length: k }, () => new Array(k).fill(0));
  for (let v = 1; v <= k; v++) matrix[rowIdx.get(v)][colIdx.get(v)] = v;
  return matrix;
}
public int[][] buildMatrix(int k, int[][] rowConditions, int[][] colConditions) {
    int[] rowOrder = topoSort(k, rowConditions);
    int[] colOrder = topoSort(k, colConditions);
    if (rowOrder.length == 0 || colOrder.length == 0) return new int[0][0];
    int[] rowIdx = new int[k + 1], colIdx = new int[k + 1];
    for (int i = 0; i < k; i++) rowIdx[rowOrder[i]] = i;
    for (int i = 0; i < k; i++) colIdx[colOrder[i]] = i;
    int[][] matrix = new int[k][k];
    for (int v = 1; v <= k; v++) matrix[rowIdx[v]][colIdx[v]] = v;
    return matrix;
}

int[] topoSort(int k, int[][] conds) {
    List<List<Integer>> adj = new ArrayList<>();
    for (int v = 0; v <= k; v++) adj.add(new ArrayList<>());
    int[] indeg = new int[k + 1];
    for (int[] c : conds) { adj.get(c[0]).add(c[1]); indeg[c[1]]++; }
    Deque<Integer> queue = new ArrayDeque<>();
    for (int v = 1; v <= k; v++) if (indeg[v] == 0) queue.add(v);
    int[] order = new int[k];
    int n = 0;
    while (!queue.isEmpty()) {
        int v = queue.poll();
        order[n++] = v;
        for (int nxt : adj.get(v))
            if (--indeg[nxt] == 0) queue.add(nxt);
    }
    return n == k ? order : new int[0];
}
vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions,
                                vector<vector<int>>& colConditions) {
    auto topoSort = [&](vector<vector<int>>& conds) {
        vector<vector<int>> adj(k + 1);
        vector<int> indeg(k + 1, 0), order;
        for (auto& c : conds) { adj[c[0]].push_back(c[1]); indeg[c[1]]++; }
        queue<int> q;
        for (int v = 1; v <= k; v++) if (indeg[v] == 0) q.push(v);
        while (!q.empty()) {
            int v = q.front(); q.pop();
            order.push_back(v);
            for (int nxt : adj[v])
                if (--indeg[nxt] == 0) q.push(nxt);
        }
        if ((int)order.size() != k) order.clear();
        return order;
    };
    vector<int> rowOrder = topoSort(rowConditions);
    vector<int> colOrder = topoSort(colConditions);
    if (rowOrder.empty() || colOrder.empty()) return {};
    vector<int> rowIdx(k + 1), colIdx(k + 1);
    for (int i = 0; i < k; i++) rowIdx[rowOrder[i]] = i;
    for (int i = 0; i < k; i++) colIdx[colOrder[i]] = i;
    vector<vector<int>> matrix(k, vector<int>(k, 0));
    for (int v = 1; v <= k; v++) matrix[rowIdx[v]][colIdx[v]] = v;
    return matrix;
}
Time: O(k² + n) Space: O(k² + n)