# Print Binary Tree

[https://leetcode.com/problems/print-binary-tree/description/](https://leetcode.com/problems/print-binary-tree/description/)

> Print a binary tree in an m\*n 2D string array following these rules:
>
> The row number m should be equal to the height of the given binary tree.
>
> The column number n should always be an odd number.
>
> The root node's value (in string format) should be put in the exactly middle of the first row it can be put. The column and the row where the root node belongs will separate the rest space into two parts (left-bottom part and right-bottom part). You should print the left subtree in the left-bottom part and print the right subtree in the right-bottom part. The left-bottom part and the right-bottom part should have the same size. Even if one subtree is none while the other is not, you don't need to print anything for the none subtree but still need to leave the space as large as that for the other subtree. However, if two subtrees are none, then you don't need to leave space for both of them.
>
> Each unused space should contain an empty string "".
>
> Print the subtrees following the same rules.

## Thoughts

结果的宽度相当于full binary tree的宽度，因此是2^h - 1.主要是要观察到父和子所在位置的关系。看到root正好在中间，是类似二分一样每个结点都在其parent所括范围内的中点。每个新范围即当前结点所划分的左右两块。

## Code

```
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<string>> printTree(TreeNode* root) {
        const auto h = height(root, 0), w = (int) pow(2, h) - 1;
        vector<vector<string>> res(h, vector<string>(w, ""));
        queue<pair<TreeNode*, pair<int, int>>> q;
        q.push(make_pair(root, make_pair(0, w)));
        int d = 0;
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; ++i) {
                const auto p = q.front(); q.pop();
                const auto left = p.second.first;
                const auto right = p.second.second;
                const auto mid = left + (right - left) / 2;
                res[d][mid] = to_string(p.first->val);
                if (p.first->left) {
                    q.push(make_pair(p.first->left, make_pair(left, mid - 1)));
                }
                if (p.first->right) {
                    q.push(make_pair(p.first->right, make_pair(mid + 1, right)));
                }
            }
            ++d;
        }
        return res;
    }

private:
    int height(TreeNode* root, int h) {
        if (!root) return h;
        return max(height(root->left, h + 1), height(root->right, h + 1));
    }
};
```

```
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private int treeHeight(TreeNode node) {
        if (node == null) {
            return 0;
        }

        return Math.max(treeHeight(node.left), treeHeight(node.right)) + 1;
    }

    public List<List<String>> printTree(TreeNode root) {
        int height = treeHeight(root), cols = ((int) Math.pow(2, height)) - 1;
        List<List<String>> res = new ArrayList<>();
        for (int i = 0; i < height; i++) {
            List<String> row = new ArrayList<>();
            for (int j = 0; j < cols; j++) {
                row.add("");
            }
            res.add(row);
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        Queue<int[]> iqueue = new LinkedList<>();
        iqueue.offer(new int[]{0, ((int) Math.pow(2, height)) - 1});
        int row = 0;
        while (!queue.isEmpty()) {
            int length = queue.size();
            for (int i = 0; i < length; i++) {
                TreeNode node = queue.poll();
                int[] indices = iqueue.poll();
                int left = indices[0];
                int right = indices[1];
                int mid = left + (right - left) / 2;
                res.get(row).set(mid, String.valueOf(node.val));
                if (node.left != null) {
                    queue.add(node.left);
                    iqueue.offer(new int[] {left, mid - 1});
                }
                if (node.right != null) {
                    queue.add(node.right);
                    iqueue.offer(new int[] {mid + 1, right});
                }
            }
            row++;
        }

        return res;
    }
}
```

## Analysis

Errors:

1. 观察结点关系错误，误认为和层数有关。

时间复杂度是遍历所需的O(n)。
