1. 问题描述:
在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则:
行数 m 应当等于给定二叉树的高度。
列数 n 应当总是奇数。
根节点的值(以字符串格式给出)应当放在可放置的第一行正中间。根节点所在的行与列会将剩余空间划分为两部分(左下部分和右下部分)。你应该将左子树输出在左下部分,右子树输出在右下部分。左下和右下部分应当有相同的大小。即使一个子树为空而另一个非空,你不需要为空的子树输出任何东西,但仍需要为另一个子树留出足够的空间。然而,如果两个子树都为空则不需要为它们留出任何空间。
每个未使用的空间应包含一个空的字符串""。
使用相同的规则输出子树。
示例 1:
输入:
1
/
2
输出:
[["", "1", ""],
["2", "", ""]]
示例 2:
输入:
1
/ \
2 3
\
4
输出:
[["", "", "", "1", "", "", ""],
["", "2", "", "", "", "3", ""],
["", "", "4", "", "", "", ""]]
示例 3:
输入:
1
/ \
2 5
/
3
/
4
输出:
[["", "", "", "", "", "", "", "1", "", "", "", "", "", "", ""]
["", "", "", "2", "", "", "", "", "", "", "", "5", "", "", ""]
["", "3", "", "", "", "", "", "", "", "", "", "", "", "", ""]
["4", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]]
注意: 二叉树的高度在范围 [1, 10] 中。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/print-binary-tree
2. 思路分析:
分析题目可以知道我们需要先声明一个二维的数组来记录答案(数组元素值为空串),我们只需要在这个数组的对应位置上修改为根节点的值即可,所以首先我们需要知道当前二叉树对应的宽度和高度,这样才可以声明对应长度和宽度的二维数组,我们可以使用一个递归方法来计算二叉树的长度和宽度,怎么样将当前的根节点的值填入到二维数组的对应位置呢?我们观察题目中给出的测试用例发现根节点的位置就是当前区间宽度的一半,所以我们可以使用一个递归方法传递当前的区间范围l,r和当前根节点对应的行数d等参数,每一次在递归的时候当前行数对应的区间中点就是当前需要修改的根节点的位置,递归修改每一个根节点的值即可。
3. 代码如下:
from typing import List
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
# 求解整棵树的高度和宽度
def dfs(self, root: TreeNode):
if not root: return [0, 0]
l = self.dfs(root.left)
r = self.dfs(root.right)
return [max(l[0], r[0]) + 1, max(l[1], r[1]) * 2 + 1]
def pt(self, root: TreeNode, l: int, r: int, d: int, res: List[List[str]]):
if not root: return
# 观察规律可以发现需要修改的根节点的位置为当前行数对应的区间[l, r]的中点位置
mid = l + r >> 1
res[d][mid] = str(root.val)
self.pt(root.left, l, mid - 1, d + 1, res)
self.pt(root.right, mid + 1, r, d + 1, res)
def printTree(self, root: TreeNode) -> List[List[str]]:
t = self.dfs(root)
h, w = t[0], t[1]
res = [[""] * w for i in range(h)]
self.pt(root, 0, w - 1, 0, res)
return res