递归:1325. 删除给定值的叶子节点

给你一棵以 root 为根的二叉树和一个整数 target ,请你删除所有值为 target 的 叶子节点 。

注意,一旦删除值为 target 的叶子节点,它的父节点就可能变成叶子节点;如果新叶子节点的值恰好也是 target ,那么这个节点也应该被删除。

也就是说,你需要重复此过程直到不能继续删除。

 

示例 1:

输入:root = [1,2,3,2,null,2,4], target = 2
输出:[1,null,3,null,4]
解释:
上面左边的图中,绿色节点为叶子节点,且它们的值与 target 相同(同为 2 ),它们会被删除,得到中间的图。
有一个新的节点变成了叶子节点且它的值与 target 相同,所以将再次进行删除,从而得到最右边的图。

解题思路
树和图里面考虑一般考虑最多的算法就是bfs和dfs。在树里面,一般要以层为单位的节点考虑的话,就是跨过了左右子树的,一般就考虑bfs。树里面的bfs广度优先搜索。而如果要以左右子树为单位考虑的话,就是dfs。比如说这道题,可以用dfs来去思考。
树里面的dfs一般分为三种,就是前序遍历,中序遍历和后续遍历。一般考虑较多的就是前序遍历和后续遍历,中序遍历在二叉搜索树时会出现较多。
那么,应该是用前序遍历还是后续遍历呢?

先来看看前序遍历和后续遍历的模板:


public void dfs(TreeNode node){
  if(node){
    //这里进行跟节点有关的操作就是前序遍历
    dfs(node.left);
    dfs(node.right);
    //这里进行跟节点有关的操作就是后续遍历
  }
}
通过扇面的模板可以了解很清楚了,如果先操作节点,再操作左右子树,就是前序遍历;**如果先操作左右子树,再操作节点,就是后续遍历。**换句话说,如果选择前序遍历,默认不知道左右子树的状态;如果选择后续遍历就是已经知道了左右子树的状态。

那么对于这道题,可以看出来题目要求从叶子节点开始删。很明显,**左右子树要删完了相应的操作才会轮到父节点。**所以直接考虑后续遍历。

为了能够像题目那样可以对左右子树进行操作,这里对模板改造一下,直接返回树的节点。


public TreeNode dfs(TreeNode node){
  if(node==null)
    return null;
  //改造左子树
  TreeNode left=dfs(node.left); node.left=left;
  //改造右子树
  TreeNode right=dfs(node.right); node.right=right;
  //对节点进行操作
  //
  return node;
}
有了模板之后,还要根据题目要求增加细节。题目中说要删除值为target的叶子节点。而我们默认左右子树已经操作完了,就是说左右子树已经删完了。所以只用考律节点,也就是说,如果节点是叶子节点,而且节点值为target就直接返回null。

那么节点操作的代码如下:


if(node.left==null&&node.right==null&&node.val==target)
  return null;

完整代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode dfs(TreeNode node, int target){
      if(node==null)
        return null;
      //对左右子树进行操作
      TreeNode left=dfs(node.left,target);
      TreeNode right=dfs(node.right,target);
      node.left=left;
      node.right=right;
      //对节点进行操作
      if(node.left==null&&node.right==null&&node.val==target)
        return null;
      return node;
    }
    public TreeNode removeLeafNodes(TreeNode root, int target) {
        if(root==null)
          return null;
        return dfs(root,target);
    }
}

 

作者:sagittarius-l
链接:https://leetcode-cn.com/problems/delete-leaves-with-a-given-value/solution/java-shu-de-hou-xu-bian-li-xiang-guan-wen-ti-by-sa/

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页