二叉树中的深搜

题目

1.2331. 计算布尔二叉树的值

1.题目描述

给你一颗完整二叉树的根,这个树有以下特征:1.叶子节点要么值为1,要么值为0 其中0表示False 1表示True

2.非叶子节点要么值为2,要么值为3,其中2表示逻辑或,3表示逻辑与

计算一个节点的值的方式如下:如果节点是个叶子节点,那么节点的值为他本身,即True或False

否则,计算两个孩子的节点值,然后将该节点的运算符对两个孩子进行运算

返回根结点root的布尔运算值

完整二叉树是每个节点有0个或者2个孩子的二叉树

叶子节点是没有孩子的节点

2.算法原理

递归重要的是能发现重复子问题

递归dfs 要知道一个树是true还是False 就要知道他的左右孩子是true还是false

宏观看待dfs

boolean dfs(root)函数头

函数体: boolean left = dfs(root.left)

boolean right = dfs(root.right)

然后判断,遇到叶子节点,返回结果

3.代码实现

java 复制代码
class Solution {
    public boolean evaluateTree(TreeNode root) {
        if(root.left==null){
            return root.val==0?false:true;
        }
        boolean left = evaluateTree(root.left);
        boolean right = evaluateTree(root.right);
        if(root.val==2){
            return left || right;
        }else{
            return left && right;
        }
    }
}

2.129. 求根节点到叶节点数字之和

1.题目描述

给你一个二叉树的根节点root,树中每个节点都存放一个0到0之间的数字 每条从根节点到叶节点的路径都代表一个数字

例如,从根节点到叶节点的路径1->2->3代表数字123

计算从根节点到叶节点的所有数字之和

叶节点是指没有子节点的节点

2.算法原理

相同的子问题: 在没遇到叶子节点之前给当前的数字*10+左孩子或右孩子的节点的值

递归出口 是遇到叶子节点

函数头的设计 int dfs(root,preSum)

函数体:先判断是否是叶子节点,如果是叶子节点返回上一个节点传来的值

preSum = 上一个递归传来的值*10加上该节点的值

如果不是分别遍历左右孩子 ret+= dfs(root.left,preSum) ret += dfs(root.right,preSum)

最后返回ret

3.代码实现

java 复制代码
class Solution {
    public int sumNumbers(TreeNode root) {
        return dfs(root,0);
    }
    public int dfs(TreeNode root,int preSum){
        preSum = preSum * 10 + root.val;
        if(root.left==null&&root.right==null){
            return preSum;
        }
        int ret = 0;
        if(root.left!=null){
            ret+=dfs(root.left,preSum);
        }
        if(root.right!=null){
            ret+=dfs(root.right,preSum);
        }
        return ret;
    }
}

3.814. 二叉树剪枝

1.题目描述

给你二叉树的根节点root,此外数树的每个节点的值要么是0,要么是1

返回移除了所有不包含1的子树的原二叉树

节点node的子树为node本身加上所有node的后代

2.算法原理

这道题是一个后序遍历

通过决策树,抽象出递归的三个核心问题

1.函数头 Node dfs(root)

2.函数体: 1.处理左子树 2.处理右子树 3.判断 左子树为null &&右子树null && 自己值为0 返回null 否则返回自己

3.递归出口,当root==null 返回null

3.代码实现

java 复制代码
class Solution {
    public TreeNode pruneTree(TreeNode root) {
        if(root==null){
            return null;
        }
        root.left = pruneTree(root.left);
        root.right = pruneTree(root.right);
        if(root.left==null&&root.right==null&&root.val==0){
            root = null;
        }
        return root;
    }
}

4.98. 验证二叉搜索树

1.题目描述

给你一个二叉树的根节点root,判断其是否是一个有效的二叉搜索树

有效的二叉搜索树定义如下:

1.节点的右子树只包含严格小于当前节点的数

2.节点的左子树只包含严格大于当前节点的数

3.所有的左子树和右子树自身也必须是二叉搜索树

2.算法原理

二叉搜索树的中序遍历的结果是一个有序的序列

搞一个全局变量定义为无穷小

策略一:

左子树是一个二叉搜索树 当前节点符合二叉搜索树的定义,右子树也是二叉搜索树

策略二:剪枝

当有一个不符合二叉搜索树定义的节点时,剩下的不用遍历了,向上返回false

3.代码实现

java 复制代码
class Solution {
    long prev = Long.MIN_VALUE;
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return true;
        }
        boolean left = isValidBST(root.left);
        if(!left){
            return false;
        }
        boolean cur = false;
        if(root.val>prev){
            cur = true;
        }
        if(!cur){
            return false;
        }
        prev = root.val;
       boolean right = isValidBST(root.right);
        return left&&right&&cur;

    }
}

5.230. 二叉搜索树中第K小的元素

1.题目描述

给定一个二叉搜索树的根节点root,和一个整数k,请你设计一个算法查找第k小的元素(k从1开始计数)

2.算法原理

利用两个全局变量+中序遍历就可以轻松解决这个问题

一个count来计数count = k 当count减到0,ret记录要返回的值

这里可以剪枝(当找到ret直接返回)

这里我们利用二叉搜索树中序遍历的结果是有序的性质

3.代码实现

java 复制代码
class Solution {
    int ret = 0;
    int count = 0;
    public int kthSmallest(TreeNode root, int k) {
        count = k;
        dfs(root);
        return ret;
    }
    public void dfs(TreeNode root){
        if(root==null||count==0){
            return;
        }
        dfs(root.left);
        count--;
        if(count==0){
            ret = root.val;
        }
        if(count==0){
            return ;
        }
        dfs(root.right);
    }
}

6.257. 二叉树的所有路径

1.题目描述

给你一个二叉树的根节点root,按照任意顺序,返回所有从根节点到叶子节点的路径

叶子节点是指没有子节点的节点

2.算法原理

函数体 void dfs(root,path)

函数体

if(root==叶子):

if(root!=叶子):

递归出口:if(root==null) return

从根节点开始向下搜索

全局变量:Striing\[\] ret

String path(路径)(这道题不好用,但有些题很好用)

回溯是因,恢复现场是果

3.代码实现

java 复制代码
class Solution {
    List<String> ret;
    public List<String> binaryTreePaths(TreeNode root) {
        ret = new ArrayList<>();
        dfs(root,new StringBuffer());
        return ret;
    }
    public void dfs(TreeNode root,StringBuffer st){
       StringBuffer path = new StringBuffer(st);
       path.append(Integer.toString(root.val));
       if(root.left==null&&root.right==null){
        ret.add(path.toString());
        return ;
       }
       path.append("->");
       if(root.left!=null){
        dfs(root.left,path);
       }
       if(root.right!=null){
        dfs(root.right,path);
       }
    }
}
相关推荐
皓月斯语1 小时前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
春日见2 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
萌动的小火苗3 小时前
嵌入式开发中的栈与队列:任务调度为什么依赖数据结构
数据结构·c++·单片机·嵌入式硬件
叩码以求索3 小时前
统计按位或能得到最大值的子集数目(一)
数据结构·算法
tachibana23 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
星恒随风3 小时前
C++ STL 栈详解:stack 的使用、经典题目与简单模拟实现
开发语言·数据结构·c++·笔记·学习
txzrxz3 小时前
单调队列讲解
数据结构·c++·算法·单调队列
Keven_114 小时前
算法札记:树状数组的用途
数据结构·算法
cpp_25015 小时前
P1540 [NOIP 2010 提高组] 机器翻译
数据结构·c++·算法·队列·noip·洛谷题解
星恒随风7 小时前
C++ STL 详解:list 的使用、迭代器失效、模拟实现与 vector 对比
开发语言·数据结构·c++·笔记·学习·list