携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情
题目描述
给你一棵二叉树的根节点 root ,请你构造一个下标从 0 开始、大小为 m x n 的字符串矩阵 res ,用以表示树的 格式化布局 。构造此格式化布局矩阵需要遵循以下规则:
- 树的 高度 为 height ,矩阵的行数 m 应该等于 height + 1 。
- 矩阵的列数 n 应该等于 2height+1 - 1 。
- 根节点 需要放置在 顶行 的 正中间 ,对应位置为 res[0][(n-1)/2] 。
- 对于放置在矩阵中的每个节点,设对应位置为 res[r][c] ,将其左子节点放置在 res[r+1][c-2height-r-1] ,右子节点放置在 res[r+1][c+2height-r-1] 。
- 继续这一过程,直到树中的所有节点都妥善放置。
- 任意空单元格都应该包含空字符串 "" 。
返回构造得到的矩阵 res 。
示例 1:
输入:root = [1,2]
输出:
[["","1",""],
["2","",""]]
示例 2:
输入:root = [1,2,3,null,4]
输出:
[["","","","1","","",""],
["","2","","","","3",""],
["","","4","","","",""]]
提示:
- 树中节点数在范围 [1, 210] 内
- -99 <= Node.val <= 99
- 树的深度在范围 [1, 10] 内
思路
显然,先要遍历树获取height的值,然后可以构造出二维数组的大小,然后就是把节点的值放置到二维数组正确的位置中。获取height的值,我们可以使用递归的方式,当前节点的深度 = max(左子节点深度+1, 右子节点深度+1, 0)。获取了height的值后,我们考虑如果把根节点放置到对应的位置,我们定义当前应该放在第row行,col可选范围在[colStart, colEnd]之间,放置好根节点后,再递归调用方法本身去放置左子节点和右子节点,row = row + 1,左子节点的col可选范围在[colStart, (colStart+colEnd)/2-1],右子节点的col可选范围在[(colStart+colEnd)/2+1, colEnd]。
Java版本代码
class Solution {
public List<List<String>> printTree(TreeNode root) {
int depth = getDepth655(root);
int m = depth + 1;
int n = 1;
while (depth-- >= 0) {
n = n<<1;
}
n -= 1;
List<List<String>> ans = new ArrayList<>();
for (int i = 0; i < m; i++) {
List<String> list = new ArrayList<>();
for (int j = 0; j < n; j++) {
list.add("");
}
ans.add(list);
}
fillAns655(ans, 0, 0, n-1, root);
return ans;
}
private int getDepth655(TreeNode root) {
int depth = 0;
if (root.left != null) {
depth = Integer.max(depth, getDepth655(root.left) + 1);
}
if (root.right != null) {
depth = Integer.max(depth, getDepth655(root.right) + 1);
}
return depth;
}
private void fillAns655(List<List<String>> ans, int row, int colStart, int colEnd, TreeNode node) {
List<String> list = ans.get(row);
list.set((colStart+colEnd)/2, String.valueOf(node.val));
if (node.left != null) {
fillAns655(ans, row+1, colStart, (colStart+colEnd)/2-1, node.left);
}
if (node.right != null) {
fillAns655(ans, row+1, (colStart+colEnd)/2+1, colEnd, node.right);
}
}
}