Find Leaves of Binary Tree
题目
Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, repeat until the tree is empty.
Example:
Given binary tree
1
/ \
2 3
/ \
4 5
Returns[4, 5, 3], [2], [1]
.
Explanation:
- Removing the leaves
[4, 5, 3]
would result in this tree:
1
/
2
- Now removing the leaf
[2]
would result in this tree:
1
- Now removing the leaf
[1]
would result in the empty tree:
[]
Returns[4, 5, 3], [2], [1]
.
思路分析
第一眼看到这道题就想到应该是用DFS来做,因为是要求所有具体的方案。然后我就写了下面的DFS的基本实现方式:
class Solution {
public List<List<Integer>> findLeaves(TreeNode root) {
if(root == null) return new ArrayList<List<Integer>>();
List<List<Integer>> result = new ArrayList<>();
dfs(root, result, new ArrayList<Integer>());
return result;
}
public void dfs(TreeNode root, List<List<Integer>> result, List<Integer> leaves){
if (root.left == null && root.right == null){
leaves.add(root.val);
if () result.add(new ArrayList(leaves)); >>>>>>如何判断每一次leave都走完了非常困难
root = null;
}
dfs(root.left, result, leaves);
dfs(root.right, result, leaves);
}
}
这个题跟找所有path方案的最大的不同是没有办法找到每一次leave走完的判断条件。
于是参考了别人的实现方式,发现可以通过遍历得到树的高度来的同时来得到具有相同高度的节点,这个方法很巧妙,也是通过backtracking的方式来实现的。
首先得到每一个节点的高度
然后创建新的ArrayList来存放相同高度的节点
class Solution {
public List<List<Integer>> findLeaves(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
treeHeight(root, result);
return result;
}
public int treeHeight(TreeNode root, List<List<Integer>> result){
if (root == null) return -1;
int height = Math.max(treeHeight(root.left, result), treeHeight(root.right, result)) + 1;
if (result.size() == height){
result.add(new ArrayList<Integer>());
}
result.get(height).add(root.val);
root.left = null;
root.right = null;
return height;
}
}
通过这道题又重新认识并学习了求树的高度以及recursion。以前做树的高度的题的时候就只是考虑一个子问题,那就是当前节点的高度应该是left节点高度与right节点高度中的最大值再加1。知道了这个子问题之后就很容易通过递归的方式来实现了。
而这道题所利用的是通过递归求树的高度的具体实现原理,那么原理是如何实现的呢,其实就是用到了backtracking的原理,从左子树开始,通过backtracking找到每一个节点的高度,最后得到的就是root节点的高度。