【LeetCode | 第五篇】算法笔记

目录

二叉树的层序遍历

将有序数组转换为二叉搜索树

验证二叉搜索树

[二叉搜索树中第 K 小的元素](#二叉搜索树中第 K 小的元素)

二叉树的右视图


【LeetCode | 第四篇】算法笔记https://blog.csdn.net/h52412224/article/details/159018487

【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


二叉树的层序遍历

思路: BFS 队列

  1. 用队列按层遍历,每次处理一层节点。

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

  3. 循环:记录当前层节点数,遍历该层所有节点,收集值到列表;将左右子节点入队。

  4. 每一层结果存入最终列表,队列为空时结束。

java 复制代码
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) return res;
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty()) {
            int size = q.size(); // 当前层节点数
            List<Integer> level = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode node = q.poll();
                level.add(node.val);
                // 左孩子入队
                if (node.left != null) q.offer(node.left);
                // 右孩子入队
                if (node.right != null) q.offer(node.right);
            }
            res.add(level); // 加入当前层
        }
        return res;
    }
}

将有序数组转换为二叉搜索树

思路: 递归 分治

  1. 有序数组中间元素为根,左半部分为左子树,右半部分为右子树。

  2. 递归:取中点建根,递归构建左、右子树。

  3. 终止条件:左边界 > 右边界,返回 null。

java 复制代码
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return build(nums, 0, nums.length - 1);
    }
    // 递归构建:[l, r]区间
    private TreeNode build(int[] nums, int l, int r) {
        if (l > r) return null;
        int mid = l + (r - l) / 2; // 防溢出
        TreeNode root = new TreeNode(nums[mid]);
        root.left = build(nums, l, mid - 1);  // 左区间
        root.right = build(nums, mid + 1, r); // 右区间
        return root;
    }
}

验证二叉搜索树

思路1: 递归 (上下界约束)

  1. 每个节点需满足:左子树 < 根 < 右子树。

  2. 递归时传入当前节点的上下界:左子树上界为根值,右子树下界为根值。

  3. 节点值超出范围返回 false,否则递归验证左右子树。

java 复制代码
class Solution {
    public boolean isValidBST(TreeNode root) {
        return check(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    // 检查节点在 (low, high) 范围内
    private boolean check(TreeNode node, long low, long high) {
        if (node == null) return true;
        // 超出范围,不是BST
        if (node.val <= low || node.val >= high) return false;
        // 左子树上界为当前值,右子树下界为当前值
        return check(node.left, low, node.val) 
            && check(node.right, node.val, high);
    }
}

思路2: 中序遍历 (升序验证)

  1. BST 中序遍历必为严格升序。

  2. 中序遍历,记录前一个节点值,当前值必须 > 前值。

  3. 用递归或迭代实现中序,遍历中判断。

java 复制代码
class Solution {
    private long pre = Long.MIN_VALUE;
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        // 左
        if (!isValidBST(root.left)) return false;
        // 当前 <= 前值,不满足升序
        if (root.val <= pre) return false;
        pre = root.val;
        // 右
        return isValidBST(root.right);
    }
}

二叉搜索树中第 K 小的元素

思路1: 递归 中序遍历

  1. 二叉搜索树的中序遍历 是严格升序,第 k 个访问的节点即为第 k 小。

  2. 递归进行中序遍历,用计数器记录访问次数,计数器等于 k 时记录答案。

  3. 提前剪枝:找到答案后直接返回,无需继续遍历。

java 复制代码
class Solution {
    private int count = 0;
    private int res = 0;
    public int kthSmallest(TreeNode root, int k) {
        inorder(root, k);
        return res;
    }
    // 中序递归
    private void inorder(TreeNode node, int k) {
        if (node == null) return;
        inorder(node.left, k);   // 左
        count++;                 // 计数+1
        if (count == k) {        // 找到第k小
            res = node.val;
            return;
        }
        inorder(node.right, k);  // 右
    }
}

思路2:迭代 中序遍历

  1. 用栈模拟中序遍历,每次弹出节点即为升序访问。

  2. 弹出节点时计数器加 1,计数器等于 k 时直接返回节点值。

  3. 无需遍历整棵树,找到即返回,效率高。

java 复制代码
class Solution {
    public int kthSmallest(TreeNode root, int k) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode curr = root;
        int count = 0;
        while (curr != null || !stack.isEmpty()) {
            // 一直往左走
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }
            // 弹出访问
            curr = stack.pop();
            count++;
            if (count == k) return curr.val; // 找到返回
            curr = curr.right;
        }
        return -1;
    }
}

二叉树的右视图

思路1: BFS 层序遍历

  1. 右视图 = 每一层最右侧节点

  2. 层序遍历,每层只取最后一个节点加入结果。

  3. 队列按层处理,记录每层节点数,遍历到最后一个节点时收集。

java 复制代码
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) return res;
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty()) {
            int size = q.size();
            // 遍历当前层
            for (int i = 0; i < size; i++) {
                TreeNode node = q.poll();
                // 每层最后一个节点加入结果
                if (i == size - 1) res.add(node.val);
                if (node.left != null) q.offer(node.left);
                if (node.right != null) q.offer(node.right);
            }
        }
        return res;
    }
}

思路2: DFS 递归 (优先右)

  1. 优先遍历右子树,每层第一个访问的节点即为右视图节点。

  2. 用深度控制层数,深度等于结果列表长度时,说明是该层第一个节点(最右)。

  3. 先右后左遍历,保证每层先访问右侧节点。

java 复制代码
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        dfs(root, 0, res);
        return res;
    }
    private void dfs(TreeNode node, int depth, List<Integer> res) {
        if (node == null) return;
        // 该层第一个节点(最右)
        if (depth == res.size()) res.add(node.val);
        dfs(node.right, depth + 1, res); // 先右
        dfs(node.left, depth + 1, res);  // 后左
    }
}

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

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

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

相关推荐
王伟19821 小时前
圆周率的历史发展与国际圆周率日
算法·圆周率
RDCJM2 小时前
Neo4j图数据库学习(二)——SpringBoot整合Neo4j
数据库·学习·neo4j
夜天炫安全6 小时前
数据结构中所需的C语言基础
c语言·数据结构·算法
2301_789015627 小时前
DS进阶:AVL树
开发语言·数据结构·c++·算法
码农的小菜园10 小时前
gradle常用指令使用笔记
笔记
qyzm10 小时前
天梯赛练习(3月13日)
开发语言·数据结构·python·算法·贪心算法
逆境不可逃10 小时前
LeetCode 热题 100 之 64. 最小路径和 5. 最长回文子串 1143. 最长公共子序列 72. 编辑距离
算法·leetcode·动态规划
鸟电波10 小时前
硬件笔记——示波器篇
笔记
Don.TIk11 小时前
SpringCloud学习笔记
笔记·学习·spring cloud