Skip to content

Latest commit

 

History

History
123 lines (88 loc) · 3.44 KB

0314.md

File metadata and controls

123 lines (88 loc) · 3.44 KB

Level: Medium

Topic: Tree Binary Tree Depth First Search Breadth First Search Hash Table

Question

Given the root of a binary tree, return the vertical order traversal of its nodes' values. (i.e., from top to bottom, column by column).

If two nodes are in the same row and column, the order should be from left to right.

Input: root = [3,9,20,null,null,15,7]
Output: [[9],[3,15],[20],[7]]

Intuition

The most intuitive way is to use bfs, level order traversal. Because it's already from top to bottom and left to right.

Starting from the root, it's at column 0 and it's left child is at column -1 and right child at column 1.

Iterative:

  • use a hashmap to store every column's list of node value
  • use a queue of pair to traverse the tree and add to map based on its column index
  • instead of sorting, make note of the minimum column index

Recursive:

  • similar to iterative, but has to store every node to hashmap to deal with level traverse problem
  • when adding to the final list, sort the list based on its level

Code

Time: O(n)
Space: O(n)

Iterative

public List<List<Integer>> verticalOrder(TreeNode root) {
    List<List<Integer>> ans = new ArrayList<>();

    int minIndex = 0;
    HashMap<Integer, List<Integer>> map = new HashMap<>();

    Queue<Pair<TreeNode, Integer>> queue = new LinkedList<>();
    if (root != null)
        queue.add(new Pair<>(root, 0));

    while (!queue.isEmpty()) {
        Pair<TreeNode, Integer> p = queue.poll();
        TreeNode node = p.getKey();
        int col = p.getValue();

        if (!map.containsKey(col))
            map.put(col, new ArrayList<>());

        minIndex = Math.min(col, minIndex);
        map.get(col).add(node.val);

        if (node.left != null)
            queue.add(new Pair<>(node.left, col-1));
        if (node.right != null)
            queue.add(new Pair<>(node.right, col+1));
    }

    while (map.containsKey(minIndex)) {
        ans.add(map.get(minIndex++));
    }

    return ans;
}

Time: O(n log n), sort used O(log n)
Space: O(n)

Recursive

HashMap<TreeNode, Integer> nodePosition = new HashMap<>();
HashMap<Integer, List<TreeNode>> map = new HashMap<>();
int minIndex = 0;

public List<List<Integer>> verticalOrder(TreeNode root) {
    traverse(root, 0, 0);
    List<List<Integer>> ans = new ArrayList<>();
    while (map.containsKey(minIndex)) {
        Collections.sort(map.get(minIndex),
                    (a,b) -> nodePosition.get(a) - nodePosition.get(b));
        List<Integer> col = new ArrayList<>();
        for (TreeNode node: map.get(minIndex))
            col.add(node.val);

        ans.add(col);
        minIndex++;
    }

    return ans;
}

private void traverse(TreeNode root, int index, int level) {
    if (root == null)
        return;

    minIndex = Math.min(minIndex, index);
    if (!map.containsKey(index))
        map.put(index, new ArrayList<>());

    nodePosition.put(root, level);
    map.get(index).add(root);

    traverse(root.left, index-1, level+1);
    traverse(root.right, index+1, level+1);
}