二叉树中的深搜

题目

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 小时前
数据结构从零开始④:堆——一种特殊的完全二叉树(附堆排序、TopK问题)
数据结构
WL学习笔记1 小时前
顺序表详解
c语言·数据结构
sugar__salt1 小时前
深入吃透前端线性数据结构:数组、栈、队列、链表核心原理与实战
前端·数据结构·链表
8Qi82 小时前
LeetCode 32:最长有效括号 —— 栈 + 标记法 题解
java·数据结构·算法·leetcode·职场和发展··括号匹配
洛水水3 小时前
【力扣100题】76.搜索插入位置
数据结构·算法·leetcode
满怀冰雪3 小时前
第07篇-差分算法-高效处理区间修改问题
数据结构·算法
先吃饱再说4 小时前
JavaScript栈和队列:从“冰柜里的雪糕”到“排队打饭”
javascript·数据结构
papership4 小时前
入门级-数据结构-2、简单树:二叉树的遍历(前序、中序、后序)
数据结构·算法
WWW65264 小时前
代码随想录 打卡第五十四天
数据结构·c++·算法