题目
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);
}
}
}