Graph

427. Construct Quad Treearrow-up-right

Recursion + tree / 2D graph

/**
 * Definition for _Node.
 * class _Node {
 *     val: boolean
 *     isLeaf: boolean
 *     topLeft: _Node | null
 * 	topRight: _Node | null
 * 	bottomLeft: _Node | null
 * 	bottomRight: _Node | null
 * 	constructor(val?: boolean, isLeaf?: boolean, topLeft?: _Node, topRight?: _Node, bottomLeft?: _Node, bottomRight?: _Node) {
 *         this.val = (val===undefined ? false : val)
 *         this.isLeaf = (isLeaf===undefined ? false : isLeaf)
 *         this.topLeft = (topLeft===undefined ? null : topLeft)
 *         this.topRight = (topRight===undefined ? null : topRight)
 *         this.bottomLeft = (bottomLeft===undefined ? null : bottomLeft)
 *         this.bottomRight = (bottomRight===undefined ? null : bottomRight)
 *   }
 * }
 */


function construct(grid: number[][]): _Node | null {
    const m = grid.length, n = grid[0].length;
    return constructTree(grid, 0, m - 1, 0, n - 1);
};

function constructTree(grid: number[][], tLeft: number, tRight: number, bLeft: number, bRight: number): _Node | null {
    if (tLeft > tRight || bLeft > bRight || tRight - tLeft !== bRight - bLeft) {
        return null;
    }
    if (tLeft === tRight && bLeft === bRight) {
        return new _Node(grid[tLeft][bLeft] === 1, true, null, null, null, null);
    }
    if (isLeaf(grid, tLeft, tRight, bLeft, bRight)) {
        return new _Node(grid[tLeft][bLeft] === 1, true, null, null, null, null);
    }
    const tMid = Math.floor((tLeft + tRight) / 2);
    const bMid = Math.floor((bLeft + bRight) / 2);
    return new _Node(grid[tLeft][bLeft] === 1, 
        false, 
        constructTree(grid, tLeft, tMid, bLeft, bMid), // topLeft
        constructTree(grid, tLeft, tMid, bMid + 1, bRight), // topRight
        constructTree(grid, tMid + 1, tRight, bLeft, bMid), // bottomLeft
        constructTree(grid, tMid + 1, tRight, bMid + 1, bRight)); // bottomRight
}

function isLeaf(grid: number[][], tLeft: number, tRight: number, bLeft: number, bRight: number) {
    const val = grid[tLeft][bLeft];
    for (let i = tLeft; i <= tRight; i++) {
        for (let j = bLeft; j <= bRight; j++) {
            if (grid[i][j] !== val) return false;
        }
    }
    return true;
}

Convert edge to graph map. DFS traverse from 0 node, assign new id every time. Use arrays ids[] and low[] to store the corresponding ids and the low index of the connect graph. If next node is unvisited, DFS to next node. Update low[curt] after the traverse by low[curt] = Math.min(low[curt], low[next]). Add to result if ids[curt] < low[next]

Use maxHeap to store a new class (val, x, y). Every time it pops the largest node, and maintain a min from the val.

Use PQ instead of Set as we can get the next stops in lexicographical order. DFS to the end of next and use bottom-up to construct itinerary.

Get the largest time spent on each level.

Last updated

Was this helpful?