题目地址:
https://leetcode.com/problems/print-binary-tree/
给定一棵二叉树,要求将其打印出来,返回字符串列表的列表,该列表里一共有树的高度个列表,每个列表的长度是
2
h
−
1
2^h-1
2h−1,并且:
1、树根应该在res[0][(n-1)/2]
;
2、对于在res[r][c]
的节点,其左孩子应该在res[r+1][c-2^(height-r-1)]
,其右孩子应该在res[r+1][c+2^(height-r-1)]
;
3、以空串表示null节点;
先求树高,然后将列表建出来,填上空串,接着用DFS把节点数值填上去。在DFS的时候,把该子树的节点填充的下标范围作为参数传递,每次填的时候就把当前节点填到当前深度所对应的列表的中间位置,然后递归填左右子树。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<List<String>> printTree(TreeNode root) {
List<List<String>> res = new ArrayList<>();
int h = getHeight(root);
for (int i = 0; i < h; i++) {
List<String> list = new ArrayList<>();
for (int j = 0; j < (1 << h) - 1; j++) {
list.add("");
}
res.add(list);
}
dfs(root, 0, 0, (1 << h) - 1, res);
return res;
}
private void dfs(TreeNode cur, int depth, int l, int r, List<List<String>> res) {
if (cur == null) {
return;
}
int mid = l + (r - l >> 1);
// 把树根填在范围的中间位置
res.get(depth).set(mid, String.valueOf(cur.val));
// 递归填写左右子树
dfs(cur.left, depth + 1, l, mid, res);
dfs(cur.right, depth + 1, mid + 1, r, res);
}
private int getHeight(TreeNode root) {
if (root == null) {
return 0;
}
return 1 + Math.max(getHeight(root.left), getHeight(root.right));
}
}
class TreeNode {
int val;
TreeNode left, right;
public TreeNode(int val) {
this.val = val;
}
}
时间复杂度 O ( h 2 h + n ) O(h2^h+n) O(h2h+n),空间 O ( h ) O(h) O(h)。