题目地址:
https://www.lintcode.com/problem/find-leaves-of-binary-tree/description
给定一个二叉树,要求返回其叶子节点,然后将叶子节点删去,继续返回叶子节点,继续删去叶子,直到树空。返回每次得到的叶子节点。
更快的 O ( n ) O(n) O(n)的方法参考https://blog.csdn.net/qq_46105170/article/details/106248333。下面介绍一个逐次删掉叶子的方法:
思路是DFS,开一个函数对二叉树做DFS,每次DFS的时候,将叶子收集在一个列表里,同时删除掉叶子节点;删除的方式是,将这个函数的返回值设为删掉所有叶子后的二叉树的树根,这样就可以在到达叶子的时候返回null回去连到上一层的树根上,就达到了删掉叶子的效果。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
/*
* @param root: the root of binary tree
* @return: collect and remove all leaves
*/
public List<List<Integer>> findLeaves(TreeNode root) {
// write your code here
List<List<Integer>> res = new ArrayList<>();
while (root != null) {
List<Integer> cur = new ArrayList<>();
root = dfs(root, cur);
res.add(cur);
}
return res;
}
private TreeNode dfs(TreeNode root, List<Integer> cur) {
if (root == null) {
return null;
} else if (root.left == null && root.right == null) {
cur.add(root.val);
return null;
} else {
root.left = dfs(root.left, cur);
root.right = dfs(root.right, cur);
return root;
}
}
}
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) {
val = x;
}
}
时间复杂度 O ( n 2 ) O(n^2) O(n2)(最差情况是每次删除的叶子节点个数是 1 1 1,比如整个二叉树是个链表,那么此时时间复杂度最高。可以考虑 T ( n ) = ∑ i = 1 h O ( n − l i ) T(n)=\sum_{i=1}^{h}O(n-l_i) T(n)=∑i=1hO(n−li),其中 l i l_i li是每次删除的叶子, h h h是树的高度,容易知道最差情况是二叉树是链表的时候。而若二叉树较为平衡时,时间复杂度可以降到 O ( n log n ) O(n\log n) O(nlogn)),空间 O ( h ) O(h) O(h)(除去最后返回的列表的空间)。