【剑指offer】把二叉树打印成多行 --Java实现
题解
层序遍历大家应该都不陌生,这道题最关键的点在于如何保存层数信息,用变量 deep 存储层数信息,子树的 deep+1,该 deep 可以作为 Lists 的索引:
- 当 deep >= lists 的大小,说明该层还未被存入过 lists,建立新的 list,存结点值,再把 list 存入 lists
- 当 deep < lists 的大小,说明该层已经被存储过,取出原来存在 lists 中的该层 list,把结点信息继续存入 list
由于递归和非递归算法的特点,将 deep 作为参数传递和作为 map 传递
一、非递归实现
1. 分析
层序遍历的模板是用一个队列,入队每次遇到的非空结点,出队当前最前结点,直到队列为空,遍历完成
现在为了保存层数信息,我们添加了map,每次入队新的结点,map 保存 <结点,层数> 的 <K,V> 对
关于相同层数如何入 lists,前面也讨论这就不赘述了
2. 代码
import java.util.*; /* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { ArrayList<ArrayList<Integer>> Print(TreeNode root) { ArrayList<ArrayList<Integer>> lists = new ArrayList<>(); HashMap<TreeNode, Integer> map = new HashMap<>(); if (root == null) { return lists; } Deque<TreeNode> queue = new ArrayDeque<>(); queue.addFirst(root); map.put(root, 0); while (!queue.isEmpty()) { root = queue.pollLast(); int deep = map.get(root); if (root.left != null) { queue.addFirst(root.left); map.put(root.left, deep + 1); } if (root.right != null) { queue.addFirst(root.right); map.put(root.right, deep + 1); } if (lists.size() <= deep) { ArrayList<Integer> list = new ArrayList<>(); list.add(root.val); lists.add(list); } else { ArrayList<Integer> list = lists.get(deep); list.add(root.val); } } return lists; } }
3. 复杂度
时间复杂度:
空间复杂度:
二、递归实现
1. 分析
其实我们层序遍历一般不会用递归实现,但是这道题比较特殊,特殊之处在于,保存层数的 deep 可以索引出对应的层信息,方便结点直接找到同一层其他结点
我们考虑的问题就变成如何让同一层结点从左到右依次打印,第一个要点肯定是保证入队的顺序,先左子树,后右子树,再一个要点是需要保证建立 list 的顺序,即上一层的 list 先建立先存储进 lists,综合考虑,选用前序遍历的模板
关于相同层数如何入 lists,前面也讨论这就不赘述了
2. 代码
import java.util.ArrayList; /* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) { ArrayList<ArrayList<Integer>> lists = new ArrayList<>(); if (pRoot == null) { return lists; } dfs(pRoot, 0, lists); return lists; } private void dfs(TreeNode pRoot, int deep, ArrayList<ArrayList<Integer>> lists) { if (pRoot == null) { return; } if (deep >= lists.size()) { ArrayList<Integer> list = new ArrayList<>(); list.add(pRoot.val); lists.add(list); } else { ArrayList<Integer> list = lists.get(deep); list.add(pRoot.val); } dfs(pRoot.left, deep + 1, lists); dfs(pRoot.right, deep + 1, lists); } }
3. 复杂度
时间复杂度:
空间复杂度: