【树】B020_删点成林(递归)

一、题目描述

Given the root of a binary tree, each node in the tree has a distinct value.

After deleting all nodes with a value in to_delete, we are left with a forest (a disjoint union of trees).

Return the roots of the trees in the remaining forest.  You may return the result in any order.

Input: root = [1,2,3,4,5,6,7], to_delete = [3,5]
Output: [[1,2,null,4],[6],[7]]

二、题解

方法一:后序

* 第一次写的时候,没有注意到 Java 的是引用传递,直接断开 root 是行不通的,

boolean[] del;
List<TreeNode> res;
public List<TreeNode> delNodes(TreeNode root, int[] to_delete) {
  res = new LinkedList<>();
  del = new boolean[1001];
  for (int d : to_delete) del[d] = true;
  
  if (root != null) //1
  	res.add(root);

  dfs(root);     
  return res;
}
void dfs(TreeNode root) {
  if (root == null) 
  	return;
  dfs(root.left);
  dfs(root.right);
  
  if (del[root.val]) {
    del[root.val] = false;
    if (root.left != null)  res.add(root.left);
    if (root.right!= null)  res.add(root.right);
    root = null;
  }
}

*两个易错点:

  1. 不能把 dfs 放在开头判 root 是否为空的前面,因为 root 有可能是被删除的结点。如果 dfs 深搜之后还不为空时,证明他不是被删除的结点,这是可以把以 root 为根的树添加进结果集 res。
  2. 因为 Java 是引用传递,所以在方法中直接对引用进行赋值不会改变引用的指向,需要借助返回值进而通过递归结束后赋值。
boolean[] del;
List<TreeNode> res;
public List<TreeNode> delNodes(TreeNode root, int[] to_delete) {
  del = new boolean[1050];
  res = new LinkedList<>();
  for (int d : to_delete) del[d] = true;
  //if (root != null) 		1
  //    res.add(root);
  root = dfs(root);
  if (root != null)
     res.add(root);
  return res;
}
private TreeNode dfs(TreeNode root) {
  if (root == null) {
    return null;
  }
  root.left = dfs(root.left);
  root.right= dfs(root.right);
  if (del[root.val]) {
    if (root.left != null)  res.add(root.left);
    if (root.right!= null)  res.add(root.right);
    return null;	//2
  }
  return root;		//2
}

复杂度分析

  • 时间复杂度: O ( n ) O(n)
  • 空间复杂度: O ( n / l o g n ) O(n / logn)

方法二:


复杂度分析

  • 时间复杂度: O ( ) O()
  • 空间复杂度: O ( ) O()
发布了495 篇原创文章 · 获赞 105 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104882817