【LeetCode | 第四篇】算法笔记

目录

二叉树

二叉树的中序遍历

二叉树的最大深度

翻转二叉树

对称二叉树

二叉树的直径


【LeetCode | 第三篇】算法笔记https://blog.csdn.net/h52412224/article/details/158689782?spm=1001.2014.3001.5502【LeetCode | 第二篇】算法笔记https://blog.csdn.net/h52412224/article/details/158467673?spm=1001.2014.3001.5502【LeetCode | 第一篇】算法笔记https://blog.csdn.net/h52412224/article/details/157903186


二叉树

二叉树的中序遍历

思路 1: 递归

递归 终止条件 :当当前节点为 null 时,直接返回(无节点可访问)。

递归 逻辑

  • 先递归遍历当前节点的左子树

  • 访问当前节点(将值加入结果列表);

  • 再递归遍历当前节点的右子树

java 复制代码
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorderHelper(root, result);
        return result;
    }
 
    private void inorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) {
            return; // 终止条件:空节点直接返回
        }
        inorderHelper(node.left, result); // 1. 遍历左子树
        result.add(node.val); // 2. 访问根节点
        inorderHelper(node.right, result); // 3. 遍历右子树
    }
}

思路 2:迭代法

初始化一个栈和结果列表,定义指针 curr 指向根节点;

循环条件:curr != null 或栈不为空;

内层循环:将 curr 及其所有左子节点依次压入栈(模拟递归遍历左子树),直到 currnull

弹出栈顶节点(当前最左节点),访问该节点(加入结果列表);

curr 指向该节点的右子节点(继续遍历右子树)。

java 复制代码
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Deque<TreeNode> stack = new LinkedList<>(); // 双端队列模拟栈
        TreeNode curr = root;
        
        while (curr != null || !stack.isEmpty()) {
            // 1. 遍历所有左子节点,压入栈
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }
            // 2. 弹出栈顶(最左节点),访问
            curr = stack.pop();
            result.add(curr.val);
            // 3. 处理右子树
            curr = curr.right;
        }
        return result;
    }
}

二叉树的最大深度

思路1: 递归

  1. 递归的核心是将问题分解为子问题:一棵树的最大深度 = 1 + 左子树最大深度与右子树最大深度的较大值。

  2. 递归终止条件:当节点为 null 时,深度为 0(空树无节点)。

  3. 分别递归计算左、右子树的深度,取最大值加 1 即为当前树的最大深度。

java 复制代码
public class Solution {
    public int maxDepth(TreeNode root) {
        // 递归终止:空节点深度为0
        if (root == null) {
            return 0;
        }
        // 递归求左子树深度
        int leftDepth = maxDepth(root.left);
        // 递归求右子树深度
        int rightDepth = maxDepth(root.right);
        // 当前节点深度 = 左右子树最大深度 + 1
        return Math.max(leftDepth, rightDepth) + 1;
    }
}

思路2:迭代法

  1. BFS 按层遍历二叉树,每遍历完整一层,深度加 1,最终层数即为最大深度。

  2. 初始化队列,将根节点入队,深度初始为 0。

  3. 循环遍历队列:每次获取当前层节点数量,遍历该层所有节点,将其左右子节点入队;一层遍历完成后深度加 1。

  4. 队列为空时遍历结束,返回深度。

java 复制代码
public class Solution {
    public int maxDepth(TreeNode root) {
        // 空树直接返回0
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root); // 根节点入队
        int depth = 0;

        while (!queue.isEmpty()) {
            // 获取当前层节点个数
            int levelSize = queue.size();
            // 遍历当前层所有节点
            for (int i = 0; i < levelSize; i++) {
                TreeNode node = queue.poll();
                // 左子节点非空则入队
                if (node.left != null) {
                    queue.offer(node.left);
                }
                // 右子节点非空则入队
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            depth++; // 一层遍历完成,深度+1
        }
        return depth;
    }
}

翻转二叉树

思路1: 递归

  1. 递归的核心是交换当前节点的左右子树,再递归处理左右子树。

  2. 递归终止条件:当前节点为 null,直接返回。

  3. 交换当前节点的左、右孩子,然后递归翻转左子树、右子树。

java 复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归终止:空节点无需翻转
        if (root == null) {
            return null;
        }
        // 交换左右子节点
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        // 递归翻转左子树
        invertTree(root.left);
        // 递归翻转右子树
        invertTree(root.right);
        return root;
    }
}

思路2:迭代法

  1. 用队列按层遍历二叉树,逐个处理节点。

  2. 初始化队列,将根节点入队。

  3. 循环出队:取出节点,交换其左右孩子,再将左右孩子入队。

  4. 队列为空时遍历结束,返回根节点。

java 复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root); // 根节点入队
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            // 交换当前节点左右孩子
            TreeNode temp = node.left;
            node.left = node.right;
            node.right = temp;
            // 左孩子非空则入队
            if (node.left != null) {
                queue.offer(node.left);
            }
            // 右孩子非空则入队
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
        return root;
    }
}

对称二叉树

思路:递归法

  1. 对称二叉树要求:根节点左右子树镜像对称。

  2. 定义辅助函数判断两个节点是否镜像:

    1. 两个节点都为 null,返回 true

    2. 一个为 null 一个不为 null,返回 false

    3. 节点值相等,且左节点的左子树与右节点的右子树对称、左节点的右子树与右节点的左子树对称。

  3. 主函数调用辅助函数,传入根节点的左右孩子。

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
        // 空树对称
        if (root == null) {
            return true;
        }
        // 判断左右子树是否镜像
        return isMirror(root.left, root.right);
    }
    
    // 辅助函数:判断两个节点是否镜像
    private boolean isMirror(TreeNode left, TreeNode right) {
        // 都为空,对称
        if (left == null && right == null) {
            return true;
        }
        // 一个空一个非空,不对称
        if (left == null || right == null) {
            return false;
        }
        // 值相等 + 子树镜像
        return left.val == right.val 
            && isMirror(left.left, right.right) 
            && isMirror(left.right, right.left);
    }
}

二叉树的直径

思路:递归法

  1. 二叉树直径 = 任意两个节点间最长路径的节点数 - 1(边数)。

  2. 直径一定是某节点的左子树深度 + 右子树深度。

  3. 递归计算每个节点的左右子树深度,同时更新全局最大直径。

  4. 递归返回当前节点的最大深度(供父节点计算)。

java 复制代码
class Solution {
    // 记录最大直径
    private int maxDiameter = 0;
    public int diameterOfBinaryTree(TreeNode root) {
        maxDepth(root);
        return maxDiameter;
    }
    // 递归计算深度,同时更新直径
    private int maxDepth(TreeNode node) {
        if (node == null) {
            return 0;
        }
        // 左子树深度
        int left = maxDepth(node.left);
        // 右子树深度
        int right = maxDepth(node.right);
        // 更新最大直径:左深度 + 右深度
        maxDiameter = Math.max(maxDiameter, left + right);
        // 返回当前节点最大深度
        return Math.max(left, right) + 1;
    }
}

上述内容也同步在我的飞书,欢迎访问

https://my.feishu.cn/wiki/QLauws6lWif1pnkhB8IcAvkhncc?from=from_copylink

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,你们的支持就是我坚持下去的动力!

相关推荐
DeepModel2 小时前
【概率分布】多项分布详解
算法·概率论
_日拱一卒2 小时前
LeetCode(力扣):只出现一次的数字
java·数据结构·算法
bulingg2 小时前
LR逻辑回归详解
算法·机器学习·逻辑回归
七七肆十九2 小时前
PTA 习题4-7 最大公约数和最小公倍数
数据结构·算法
NGC_66112 小时前
八大排序对比及实现
数据结构·算法·排序算法
进击的小头2 小时前
第7篇:动态规划的数值求解算法
python·算法·动态规划
Wyawsl2 小时前
LNMP环境部署笔记
笔记
小红卒2 小时前
Go语言安全开发学习笔记5:tls反弹shell升级到C2指令执行马
笔记·学习·网络安全·golang
FMRbpm2 小时前
斑马日记2026.3.13
数据结构·算法