時念
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
    • JavaScript 基础
  • 后端笔记

    • Java
    • Spring
    • 算法
    • 高可用
    • 高并发
  • 工作问题

    • 问题记录
  • 各类工具使用
  • GitHub技巧
  • 博客搭建
  • 面试题库

    • 零碎
    • 面试常见题目汇总
  • 面试心得

    • 面试集锦
    • 杂言碎语
  • 摘抄收录

    • ☆ 励志鸡汤
    • ❀ 人间烟火
    • ☣ 万物沦丧
    • ✌ 关掉烦恼
    • ✲ 小酒馆
  • 读书笔记

    • 《小狗钱钱》
    • 《穷爸爸富爸爸》
    • 《聪明人使用方格笔记本》
  • 学习
  • 心情杂货
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub

時念

一个有梦想的后端小菜鸡(✪ω✪)
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
    • JavaScript 基础
  • 后端笔记

    • Java
    • Spring
    • 算法
    • 高可用
    • 高并发
  • 工作问题

    • 问题记录
  • 各类工具使用
  • GitHub技巧
  • 博客搭建
  • 面试题库

    • 零碎
    • 面试常见题目汇总
  • 面试心得

    • 面试集锦
    • 杂言碎语
  • 摘抄收录

    • ☆ 励志鸡汤
    • ❀ 人间烟火
    • ☣ 万物沦丧
    • ✌ 关掉烦恼
    • ✲ 小酒馆
  • 读书笔记

    • 《小狗钱钱》
    • 《穷爸爸富爸爸》
    • 《聪明人使用方格笔记本》
  • 学习
  • 心情杂货
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub
  • java

  • spring

  • 问题记录

  • 算法

    • 链表
    • 双指针
    • 二叉树
      • 二叉树遍历 (前、中、后)
      • 层序遍历
      • 翻转二叉树
      • 对称二叉树
      • 二叉树直径
      • 将有序数组转化为二叉树
      • 验证二叉搜索树
      • 二叉树中第k个最小的元素
      • 二叉树右视图
      • 二叉树展开为链表
      • 根据前序 中序 构造二叉树
      • 路径总和 (回溯)
      • 最近公共祖先
      • 最大路径和
    • 回溯
    • (伪)二分
    • 堆
    • 贪心
    • 动态规划
    • 多维动态规划
    • 技巧
    • 数组
    • 子串
    • 滑动窗口
    • 哈希
    • (伪)栈
    • 数组混淆点整理
  • 高可用

  • 后端
  • 算法
時念
2023-12-12

二叉树

几秒前 #124 二叉树中的最大路径和 困难 1 次
8 分钟前 #236 二叉树的最近公共祖先 中等 2 次
16 分钟前 #437 路径总和 III 中等 1 次
1 小时前 #105 从前序与中序遍历序列构造二叉树 中等 1 次
2 小时前 #114 二叉树展开为链表 中等 1 次
2 小时前 #199 二叉树的右视图 中等 1 次
2 小时前 #230 二叉搜索树中第K小的元素 中等 1 次
5 小时前 #98 验证二叉搜索树 中等 7 次
5 小时前 #108 将有序数组转换为二叉搜索树 简单 1 次
6 小时前 #543 二叉树的直径 简单 2 次
6 小时前 #101 对称二叉树 简单 4 次
6 小时前 #226 翻转二叉树 简单 1 次
6 小时前 #104 二叉树的最大深度 简单 3 次
7 小时前 #102 二叉树的层序遍历 中等 1 次
7 小时前 #94 二叉树的中序遍历 简单 1次

二叉树备注:

1、二叉树的最大深度 可以用递归

2、二叉树直径 最后返回条件 +1 注意

3、前中构造二叉树的递归条件

4、路径总和3 这个要max 跟 0比较 ,最后返回 要加上当前节点的值

5、

# 二叉树遍历 (前、中、后)

class Solution {
    List<Integer> res = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
    }
}
思路:
  1、递归
  2、前:左根右 中:根左右  后:左右根
  
1
2
3
4
5
6
7
8
9

# 层序遍历

class Solution {
    public List<List<Integer>> inorderTraversal(TreeNode root) {
    }
}
思路:
  1、利用queue,如果root不为空放进去
  2、while循环开始对queue不为空判断
  3、定义item的过程list用于存储每层的数据
  4、for循环来取queue的值 i为queue的size, 采用i--的形式,然后queue采取poll的方式弹出值,并将弹出的值放入item
  5、之后对弹出值的left和right进行判断,不为空的话 放入queue,方便进行下次循环
  6、之后将item放入 最终的res中
  7、最后返回res
1
2
3
4
5
6
7
8
9
10
11
12

# 翻转二叉树

class Solution {
    public TreeNode invertTree(TreeNode root) {
    }
}
思路:
  1、递归
  2、递归终止条件判断 root 为null 返回root
  3、root的left 赋值给中间变量item
  4、root的left = 其right
  5、right等于item
  5、递归左子树
  6、递归右子树
  7、返回 root
1
2
3
4
5
6
7
8
9
10
11
12
13

# 对称二叉树

class Solution {
    public boolean isSymmetric(TreeNode root) {
    }
}
思路:
  1、需要单独定义方法递归,传值分别为 root的左子树跟右子树
  2、新的compare方法内部逻辑为: 
  		a、如果 l跟r都为空 返回true;
  		b、如果 l跟 r 任何一个为空 返回false;(两个if判断)
  		c、如果 l跟r的val 不相等也是 false;
  		d、之后分别对l 跟 r 递归 得到 ln 跟 rn
  		e、最后返回 ln && rn
	3、返回 compare 方法
1
2
3
4
5
6
7
8
9
10
11
12
13

# 二叉树直径

class Solution {
    private int res = 0;
    public int diameterOfBinaryTree(TreeNode root) {
    }
}
思路:
  1、外层定义返回结果,然后单独定义一个process方法
  2、递归终止条件判断 root == null 返回0
  3、之后分别递归 left 跟 right  得到 l 跟 r 
  4、res 就为 l+r+1跟 原来 res的最大值    res = Math.max(res, l+r+1);
  5、最后返回 l跟r的最大值 +1 用于下次递归  Math.max(l, r)+1;
  
1
2
3
4
5
6
7
8
9
10
11
12

# 将有序数组转化为二叉树

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
    }
}
思路:
  1、采用二分法 中间节点作为root节点
  2、定义新方法 process 传值分别为( num  ,l 开始0,  r 结束为num的长度-1)
  3、新方法内  如果 l  > r 返回null,说明当前节点为null
  4、之后 采用 (l+r+1)/2 的形式 找到mid 
  5、定义新的树  root 其val就是这个mid
  6、root的left采用递归,数组传进去, 开始 为l 结束为 mid-1
  7、right 同上 但开始为mid +1 结束为 r
  8、返回 root;
  9、最终返回process方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 验证二叉搜索树

class Solution {
    public boolean isValidBST(TreeNode root) {
    }
}
思路:
  1、定义一个新的process方法  传参为 root  Long最小值 l, 最大值 r
  2、方法内部 root为null 返回true
  3、得到当前节点的root的val
  4、此val 必须比 l大 r小  得到两个boolean 的判断
  5、然后 递归比较root的left跟right  传参分别是 root.left, l, mid    root.right, mid, r 同样得到两个Boolean的判断
  6、最后这四个进行 && 返回
1
2
3
4
5
6
7
8
9
10
11

# 二叉树中第k个最小的元素

class Solution {
    public int kthSmallest(TreeNode root, int k) {
    }
}
思路:
  1、遍历二叉树得到 list
  2、进行list的排序
  3、返回第k个值
1
2
3
4
5
6
7
8

# 二叉树右视图

class Solution {
    // 层序遍历的变种
    public List<Integer> rightSideView(TreeNode root) {
      
    }
}
思路:
  1、直接进行层序遍历
  2、不同: 放入res时 去最后一个元素放入
1
2
3
4
5
6
7
8
9

# 二叉树展开为链表

class Solution {
    List<TreeNode> res = new ArrayList<>();
    public void flatten(TreeNode root) {
    }
}
思路:
  1、定义新方法,先进行前序遍历  得到res
  2、对res开始从i=1遍历
  3、得到 l的值为get(i-1) r为 get(i)
  4、然后将l的left赋值为null l的right赋值为r
1
2
3
4
5
6
7
8
9
10

# 根据前序 中序 构造二叉树

class Solution {
    int[] preorder;
    Map<Integer, Integer> dic = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        for(int i = 0; i < inorder.length; i++){
            dic.put(inorder[i], i);
        }
        return process(0, 0, inorder.length - 1);
    }
    public TreeNode process(int root, int left, int right) {
        if (left > right){
          	return null;   																			// 递归终止
        }                        
        TreeNode node = new TreeNode(preorder[root]);          // 建立根节点
        int i = dic.get(preorder[root]);                       // 划分根节点、左子树、右子树
        node.left = recur(root + 1, left, i - 1);              // 开启左子树递归
        node.right = recur(root + 1 + i - left , i + 1, right); // 开启右子树递归
        return node;                                           // 回溯返回根节点
    }
}
思路:
  1、先将前序放到外层  方便下面process处理
  2、再将中序缓存到外部的map中 方便赋值
  3、在进行递归处理 传参 root 0 left 0 right inorder.length - 1 , 因为中序遍历可以确定right
  4、process内 逻辑如注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 路径总和 (回溯)

class Solution {
    public int pathSum(TreeNode root, int sum) {
        // key是前缀和, value是大小为key的前缀和出现的次数
        Map<Long, Integer> prefixSumCount = new HashMap<>();
        // 前缀和为0的一条路径
        prefixSumCount.put(0L, 1);
        // 前缀和的递归回溯思路
        return process(root, prefixSumCount, sum, 0L);
    }


    private int process(TreeNode node, Map<Long, Integer> prefixSumCount, int target, long currSum) {
        // 1.递归终止条件
        if (node == null) {
            return 0;
        }
        // 2.本层要做的事情
        int res = 0;
        // 当前路径上的和
        currSum += node.val;

        //---核心代码
        // 看看root到当前节点这条路上是否存在节点前缀和加target为currSum的路径
        // 当前节点->root节点反推,有且仅有一条路径,如果此前有和为currSum-target,而当前的和又为currSum,两者的差就肯定为target了
        // currSum-target相当于找路径的起点,起点的sum+target=currSum,当前点到起点的距离就是target
        res += prefixSumCount.getOrDefault(currSum - target, 0);
        // 更新路径上当前节点前缀和的个数
        prefixSumCount.put(currSum, prefixSumCount.getOrDefault(currSum, 0) + 1);
        //---核心代码

        // 3.进入下一层
        res += recursionPathSum(node.left, prefixSumCount, target, currSum);
        res += recursionPathSum(node.right, prefixSumCount, target, currSum);

        // 4.回到本层,恢复状态,去除当前节点的前缀和数量
        prefixSumCount.put(currSum, prefixSumCount.get(currSum) - 1);
        return res;
    }
}
思路:
  1、
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 最近公共祖先

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    }
}
思路:
  1、如果root为空 以及 root== p或者 root== q 直接返回root
  2、然后直接递归 root 左和右 p和q都是原值传入
  3、比较:l为空 返回r r为空返回l  如果都没有为空 则返回root
1
2
3
4
5
6
7
8

# 最大路径和

	class Solution {
    // 跟直径的类似
    int res = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
      
    }
  }
思路:
  1、外层定义结果res
  2、定义新方法process 进行处理, 并返回 res
  2、process内,递归结束条件 root为null 返回0
  3、分别对 l 跟 r 递归,然后跟0比较取最大值, 《这里必须对0比较,防止都是负数的情况》
  4、这个时候 res 的最大值为 res 跟 l+r +root.val 比较
  5、最后返回 l跟r的最大值 +root.val
1
2
3
4
5
6
7
8
9
10
11
12
13
14
编辑
上次更新: 2024/03/26, 9:03:00
双指针
回溯

← 双指针 回溯 →

最近更新
01
database-shard-dynamic-expand
03-26
02
README
03-26
03
database-shard-global-id-generate
03-26
更多文章>
Theme by Vdoing | Copyright © 2019-2024 時念 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式