在一个 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", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]]
首先获取列表长度,外层列表长度即树高,内层列表的长度为2的高度次方-1,首先建立一个列表,将其初始化一个包含列表长度个空串的列表。
然后进行层次遍历,每遍历一行,在结果集中添加一个列表,将当前的节点对应的串存入对应的位置。那么怎么样得到对应的位置的下标呢,这里就用到了二分搜索的思想。具体请看代码:
public List<List<String>> printTree(TreeNode root) { int height=getHigh(root);//求树的高度 List<List<String>> ans=new ArrayList<>(height); int width=(int)Math.pow(2,height)-1;//每层列表的长度 List<String > ans_lev=new ArrayList<>(); for (int i = 0; i < width; i++) ans_lev.add(""); DFS(root,ans,ans_lev,1,0,width-1);//层次遍历填充结果 return ans; } private void DFS(TreeNode root, List<List<String>> ans, List<String > ans_lev, int depth,int lo,int hi){ if(root==null) return;//深度优先的层次遍历:获取节点准确位置 if(ans.size()<depth)ans.add(new ArrayList<String>(ans_lev)); int index=(lo+hi)/2;//应该设置的位置 ans.get(depth-1).set(index,Integer.toString(root.val)); DFS(root.left,ans,ans_lev,depth+1,lo,index-1); DFS(root.right,ans,ans_lev,depth+1,index+1,hi); } private int getHigh(TreeNode root) {//求树高 if(root==null) return 0; return 1+Math.max(getHigh(root.left),getHigh(root.right)); }
官方:
public class Solution { public List<List<String>> printTree(TreeNode root) { int height = getHeight(root); String[][] res = new String[height][(1 << height) - 1]; for(String[] arr:res) Arrays.fill(arr,""); List<List<String>> ans = new ArrayList<>(); fill(res, root, 0, 0, res[0].length); for(String[] arr:res) ans.add(Arrays.asList(arr)); return ans; } public void fill(String[][] res, TreeNode root, int i, int l, int r) { if (root == null) return; res[i][(l + r) / 2] = "" + root.val; fill(res, root.left, i + 1, l, (l + r) / 2); fill(res, root.right, i + 1, (l + r + 1) / 2, r); } public int getHeight(TreeNode root) { if (root == null) return 0; return 1 + Math.max(getHeight(root.left), getHeight(root.right)); } }