二叉树中的深搜

news/2025/2/5 22:00:36/

一)计算布尔二叉树的值

2331. 计算布尔二叉树的值 - 力扣(LeetCode)

1)计算布尔二叉树需要从叶子节点向上进行计算,从下向上进行计算

2)完整二叉树是同时拥有左孩子和右孩子,或者是完全没有右孩子

3)当我只是盯着根节点来看的时候,此时我想知道我这一层的结果是什么?必须先知道这个根节点的左子树的布尔值,还需要知道右子树的布尔值,当我知道左右子树是true或者是false的时候,在我这一层把左右子树的信息整合;

4)如果想要知道左子树或者是右子树是true还是false,这不是恰好和我们的大问题是一样的吗?主问题就是解决这棵树是true还是false

5)重复子问题函数头:给定一个指针,判断以这个指针为结点的树是true还是false,求以这个节点为根节点的boolean值

6)函数体:先知道左子树是true还是false,再知道右子树是true还是false最后在本层进行整合

boolean flag1=dfs(root.left);

boolean flag2=dfs(root.right);

return root.val==2?flag1orflag2:flag1&flag2

7)递归出口:遇到叶子节点,只需要将叶子节点是true还是false返回

8)本质上这个题就是在做一个后序遍历,本质上就是一个深度优先遍历,先返回左节点的boolean值,再返回右节点的boolean值,最后再根据根结点的值进行计算,在遇到叶子节点的时候,将叶子节点的信息返回到上一层

class Solution {public boolean evaluateTree(TreeNode root) {if(root==null) return true;if(root.left==null&&root.right==null) return root.val==0?false:true;
//先进行计算左子树的boolean值boolean flag1=evaluateTree(root.left);
//再进行计算右子树的booleanboolean flag2=evaluateTree(root.right);return root.val==2?flag1|flag2:flag1&flag2;}
}

二)求根节点到叶子节点数字之和

129. 求根节点到叶节点数字之和 - 力扣(LeetCode)

1)二叉树的递归问题想一下递归到某一层的时候要干什么事情,当遍历到某一个根节点所干的事情都一样的时候,况且干这个事情能够得到最终我所想要的结果,那么这个这个事情就是相同子问题,当我们遍历到某一个根节点的时候,还是需要将这个跟跟节点的左子树之和和右子树之和计算相加返回给上一层

2)此时我们需要进行计算的点就是当遍历到某一个根节点的时候,需要知道前面的数字的信息,就比如说遍历到5的时候是需要知道12的信息的,因为当前我遍历到这一层的时候我什么也不知道,我怎么计算出1258呢?我只是知道当前根节点以及后续节点的信息,根本不知道当前根节点以前的信息

3)知道12的信息之后,再结合当前根节点进行计算出125的值,然后再将125传递给它的左子树和右子树,算出左右子树的值,最后将对应的值返回给根节点,在进行相加,返回到上一层节点

第一步:知道前面的数是12之后,进行计算当前结点的值是125 

第二步:将当前的这个125传递给以5为根节点的左子树,算出左子树的和是1258

第三步:将这个125传递给以5为根节点的右子树,计算出右子树的和是XXXX

第四步:将左子树和右子树返回的和进行相加,最后返回当前根节点的上一层

1)函数头的设计:你给我传入一个根节点之后,把以这个根节点相连的左右子树叶子之和进行返回,int dfs(Node root,int k)参数是当前传入的根节点和你传递到这个根节点的时候,从原始根节点到这个递归层次的结点的路径和,传入一个根节点,计算出以当前根节点的所有叶子节点之和进行返回

2)函数体:执行1 2 3 4步

3)递归出口:递归出口是在第二步进行执行的

class Solution {public int GetSum(TreeNode root,int k){//根据题目给定的数据范围来说不可能出现根节点的情况//遍历到叶子结点的时候才到了递归结束的出口if(root.left==null&&root.right==null){return root.val+k*10;}int current=k*10+root.val;int ret=0;//算出左子树的和if(root.left!=null) ret+=GetSum(root.left,current);//算出右子树的和if(root.right!=null) ret+=GetSum(root.right,current);//返回值是左子树和右子树的和return ret;}public int sumNumbers(TreeNode root) {return GetSum(root,0);}
}

三)二叉树剪枝:

814. 二叉树剪枝 - 力扣(LeetCode)

1)在这个问题中子问题就是给定一个头指针,将以这个头指针为根节点的所有为0的子树全部干掉,返回最后处理结果的头指针

2)当给定一个头结点的信息的时候,我必须知道以当前根节点的左子树的信息和以当前根节点的右子树的信息,必须是左子树全为0或者是右子树全为0,我才可以将左子树或者是右子树剪掉,所以需要后序遍历,因为只有出现后序遍历的时候,才能带着左子树的信息和右子树的信息;

3)进行模拟递归的过程:从叶子节点开始判断,通过决策树模拟删除递归的这样一个过程即可

1)当判断完左子树之后,我需要继续进行判断右子树也就是0的右节点,此时发现右节点的左子树和右子树也都是空,况且右节点的值也是0,所以右节点也是可以干掉的,但是此时返回到1的时候虽然发现左节点和右节点都是空,但是发现当前根节点是1,所以不能干掉

2)接下来继续判断0的右节点

3)函数体:先处理左子树,再进行处理右子树,再来处理当前节点

4)函数出口:root=null

class Solution {//给定一个根节点,返回左子树和右子树简直之后的头节点public TreeNode pruneTree(TreeNode root) {if(root==null) return null;root.left=pruneTree(root.left);
//返回左子树剪枝之后的结果,将左子树中是0的分支全部干掉,返回处理完成之后的左根节点root.right=pruneTree(root.right);
//返回右子树剪枝之后的结果,将右子树是的0的分支全部干掉,返回处理之后的右根节点//判断当前位置是否需要剪枝,如果发现左右子树都为空,况且当前节点是0,那么直接返回即可if(root.left==null&&root.right==null&&root.val==0){return null;}else{return root;}}
}

四)验证二叉搜索树

98. 验证二叉搜索树 - 力扣(LeetCode)​​​​​​

之前我的做题思路就是说先进行判断一下以当前节点为根节点的左子节点和右子节点是一颗二叉搜索树,再进行判断当前根节点的左子树是否是一颗二叉搜索树,和当前根节点的右子树是否是一颗二叉搜索树没但是这个判断方法是错误的,只能通过72个测试用例,请看上面

解法1:根据中序遍历的结果来判断这颗树是否是二叉搜索树

class Solution {public List<Integer> GetList(TreeNode root){Stack<TreeNode> stack=new Stack<>();List<Integer> list=new ArrayList<>();while(!stack.isEmpty()||root!=null){while(root!=null){stack.push(root);root=root.left;}TreeNode node=stack.pop();list.add(node.val);root=node.right;}return list;}public boolean isValidBST(TreeNode root) {List<Integer> list=GetList(root);for(int i=0;i<list.size()-1;i++){if(list.get(i)>=list.get(i+1)) return false;}return true;}
}

解法2:递归

1)首先定义一个全局变量,prev=-00,这个全局变量的意思就是在中序遍历的过程中,当进行遍历到某一个位置的时候,它的中序遍历到此位置的前驱是多少,所以仅仅需要将当前位置的节点和它的前驱节点prev进行判断一下即可,prev的作用就是当进行中序遍历到某一个节点的时候,它的前驱的值是多少;

2)剪枝:就比如说在下面这个节点中,当我遍历到19这个位置的时候发现prev=20,此时就可以直接判断这棵树不是一个二叉搜索树了,那么应该此时直接停止中序遍历,直接向上返回false,当我们在深度优先遍历的过程中,发现某一个分支绝对不存在想要的结果的时候,在本题中发现这个分支不需要在进行遍历了,如果这个分支特别长,就可以剪掉很多枝叶了,就可以加快我们的搜索过程,就是为了避免深度优先遍历一些没有意义的东西

3)左子树是一颗二叉搜索树,当前节点也是符合二叉搜索树的定义,右子树也是一颗二叉搜索树, 根据当前节点如何来进行判断呢,只需要和prev作比较即可,无序和后面的数进行比较,因为和后面的数作比较的过程中序遍历已经帮助我完成了

class Solution {long prev=Long.MIN_VALUE;public boolean isValidBST(TreeNode root) {if(root==null) return true;
boolean flag1=isValidBST(root.left);//先把判断左子树是否是一颗二叉搜索树boolean flag3=true;if(root.val<=prev) flag3= false;prev=root.val;
boolean flag2=isValidBST(root.right);//判断右节点是否是一颗二叉搜搜书return flag1&&flag2&&flag3;//如果左子树满足二叉搜索树定义,右子树满足二叉搜索树定义,况且根节点也满足二叉搜锁树定义,直接返回true}

五)二叉搜索树中第k小的元素

230. 二叉搜索树中第K小的元素 - 力扣(LeetCode)

两个全局变量+中序遍历:

使用一个全局变量count,count=k,当k最终减到0的时候,使用另一个全局变量ret来保存最终返回的结果

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) return;dfs(root.left);count--;if(count==0){ret=root.val;}dfs(root.right);}
}


http://www.ppmy.cn/news/991817.html

相关文章

.Net Core上传组件_.Net Core图片上传组件_Uploader7.0

一、.Net Core上传组件Uploader7.0简介 1.当前版本v7.0&#xff0c;前端框架丰富升级 2.前端jquery框架封装,cover.js, 腾讯云cos-js-sdk-v5.min.js 3.后端&#xff0c;支持Asp.Net 和 Asp.Net Core 矿建 4.数据传输模式支持&#xff1a;WebScoket 、Ajax、Form 模式上传到…

浏览器访问nginx转发打开oss上的html页面默认是下载,修改为预览

使用阿里云盒OSS上传了html页面&#xff0c;在nginx里配置跳转访问该页面时&#xff0c;在浏览器里直接默认下载了该页面&#xff0c;现在想实现预览功能&#xff0c;只需在nginx里的location里修改消息头的Content-Disposition为inline即可 注意要隐藏头信息proxy_hide_header…

【Linux】网络基础

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统网络编程 文章目录 一、协议初识和网络协议分层&#xff08;TCP/IP四层模型&#xff09;认识协议TCP/IP五层&#xff08;或四层&#xff09;模型 二、认识MAC地址和IP地址认识MAC地址认识IP地址认…

罗布乐思Roblox学习笔记

罗布乐思 文章目录 罗布乐思基本操作CFrameGUIModule script呼吸灯商店imageChangetag标签知识答题showTips 基本操作 缩放按shift 等比例缩放 ctrl 双向缩放 复制对象 ctrlD &#xff08;如果选择多个对象&#xff0c;按住ctrl&#xff09; F 聚焦 Workspace ​ Terrain…

使用Express部署Vue项目

使用Express部署Vue项目 目录 1. 背景 2. 配置Vue CLI 1.1 安装nodejs 1.2 创建vue-cli 1.3 创建vue项目 1.4 构建vue项目3. 配置Express 2.1 安装express 2.2 创建项目4. 使用express部署vue项目 1&#xff0c;背景 我们想要做一个前后端分离的课程项目&#xff0c;前端…

数据库选型

影响数据库选择的因素 数据量&#xff1a;是否海量数据&#xff0c;单表数据量太大会考验数据库的性能数据结构&#xff1a;结构化 (每条记录的结构都一样) 还是非结构化的 (不同记录的结构可以不一样)是否宽表&#xff1a;一条记录是 10 个域&#xff0c;还是成百上千个域数据…

Java ~ Collection/Executor ~ DelayQueue【源码】

前言 文章 相关系列&#xff1a;《Java ~ Collection【目录】》&#xff08;持续更新&#xff09;相关系列&#xff1a;《Java ~ Executor【目录】》&#xff08;持续更新&#xff09;相关系列&#xff1a;《Java ~ Collection/Executor ~ DelayQueue【源码】》&#xff08;学…

开心档之CSS !important 规则

CSS !important 规则 CSS !important 规则 CSS是网页中最常用的样式语言&#xff0c;用来改变网页的颜色、字体、布局等等。但是当多个样式规则作用于同一个元素上时&#xff0c;由于优先级的差异&#xff0c;可能会出现样式被覆盖的情况。为了解决这个问题&#xff0c;CSS中提…