本系列为笔者的 Leetcode 刷题记录,顺序为 Hot 100 题官方顺序,根据标签命名,记录笔者总结的做题思路,附部分代码解释和疑问解答,01~07为C++语言,08及以后为Java语言。

01 二叉树的层序遍历

在这里插入图片描述

在这里插入图片描述

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {//广度优先遍历 queue//1.创建queue集合,添加首节点Deque<TreeNode> queue = new LinkedList<>();queue.offer(root);//2.遍历tree,取出结点,判断结点情况List<List<Integer>> results = new ArrayList<>();if(root == null){return results;}while(!queue.isEmpty()){int size = queue.size();List<Integer> result = new ArrayList<>();for(int i=0; i<size; i++){TreeNode node = queue.poll();result.add(node.val);//3.添加左右孩子结点if(node.left != null){queue.offer(node.left);}if(node.right != null){queue.offer(node.right);}}results.add(result);}return results;}
}

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

在这里插入图片描述

在这里插入图片描述

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode sortedArrayToBST(int[] nums) {}
}

给定二叉搜索树的中序遍历,是否可以唯一地确定二叉搜索树?答案是否定的。

如果增加一个限制条件,即要求二叉搜索树的高度平衡,是否可以唯一地确定二叉搜索树?答案仍然是否定的。

直观地看,我们可以选择中间数字作为二叉搜索树的根节点,这样分给左右子树的数字个数相同或只相差 1,可以使得树保持平衡。

方法一:递归

BST 是 Binary Search Tree(二叉搜索树)的缩写。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {//1.构建递归函数,传递左右区间参数return helper(nums, 0, nums.length-1);}public TreeNode helper(int[] nums, int left, int right){if(left > right){ //特殊情况判断return null;}//2.添加当前root结点int mid = (left + right) / 2;TreeNode root = new TreeNode(nums[mid]);//3.递归添加左右孩子结点root.left = helper(nums, left, mid - 1);root.right = helper(nums, mid + 1, right);return root;}
}

03 验证二叉搜索树

在这里插入图片描述

在这里插入图片描述

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean isValidBST(TreeNode root) {}
}

这启示我们设计一个递归函数 helper(root, lower, upper) 来递归判断,函数表示考虑以 root 为根的子树,判断子树中所有节点的值是否都在 (l,r) 的范围内(注意是开区间)。如果 root 节点的值 val 不在 (l,r) 的范围内说明不满足条件直接返回,否则我们要继续递归调用检查它的左右子树是否满足,如果都满足才说明这是一棵二叉搜索树。

方法一:递归

class Solution {public boolean isValidBST(TreeNode root) {//1.构建递归函数,传递左右区间参数return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);}public boolean helper(TreeNode root, long lower, long upper){if(root == null){ //特殊情况判断return true;}//2.判断当前root结点if(root.val <= lower || root.val >= upper){return false;}//3.递归判断左右孩子结点return helper(root.left, lower, root.val) && helper(root.right, root.val, upper);}
}

Long.MIN_VALUELong.MAX_VALUE是啥?

  • Long.MIN_VALUE-2^63,即 -9,223,372,036,854,775,808。代表 long 类型变量可以存储的最小值。
  • Long.MAX_VALUE2^63 - 1,即 9,223,372,036,854,775,807。代表 long 类型变量可以存储的最大值。

方法二:中序遍历

class Solution {public boolean isValidBST(TreeNode root) {if(root == null){return true;}//queue: 创建 -> 当前 -> 孩子//stack: 创建 -> 左移 -> 右移//1.创建Deque<TreeNode> stack = new LinkedList<>();long inorder = Long.MIN_VALUE;while(!stack.isEmpty() || root != null){//2.左移while(root != null){stack.push(root);root = root.left;}root = stack.pop();if(root.val <= inorder){return false;}inorder = root.val;//3.右移root = root.right;}return true;}
}

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

在这里插入图片描述

在这里插入图片描述

方法一:递归

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {int flag1, flag2;public int kthSmallest(TreeNode root, int k) {flag1 = k;flag2 = 0;return inorder(root);}//1.创建public int inorder(TreeNode root){if(root == null){return -1;}//2.左右孩子结点int left = inorder(root.left);if(left != -1){return left;}flag2++;if(flag2 == flag1){return root.val;}//3.返回return inorder(root.right);}
}

方法二:栈

05 二叉树的右视图

在这里插入图片描述

在这里插入图片描述

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> rightSideView(TreeNode root) {}
}

方法一:深度优先搜索(stack)

class Solution {public List<Integer> rightSideView(TreeNode root) {Map<Integer, Integer> map = new HashMap<>(); //深度,valint maxDepth = -1; //标记//1.创建并加入Deque<TreeNode> nodeStack = new LinkedList<>();Deque<Integer> depthStack = new LinkedList<>();nodeStack.push(root);depthStack.push(0);while(!nodeStack.isEmpty()){//2.弹出并判断TreeNode node = nodeStack.pop();int depth = depthStack.pop();if(node != null){maxDepth = Math.max(maxDepth, depth); //标记更新//⭐if(!map.containsKey(depth)){map.put(depth, node.val);}//3.左右孩子结点nodeStack.push(node.left);nodeStack.push(node.right);depthStack.push(depth + 1);depthStack.push(depth + 1);}}//⭐List<Integer> result = new ArrayList<>();for(int i=0; i<=maxDepth; i++){result.add(map.get(i));}return result;}
}

Deque是啥意思?

DequeDouble Ended Queue(双端队列) 的缩写,是一个接口,常用实现有LinkedListArrayDeque,既可以用作队列(先进先出),也可以用作(后进先出)。

② 这个代码是怎么保证每次栈弹出的都是没加入map的最右端结点?

因为栈是后进先出,右孩子会先被弹出访问。所以在访问该层节点时,第一个被访问到的节点是右孩子,也就是该层最右边的节点。

③ 为什么maxDepth 赋值为0,会出现解答错误?

  • 当树为空时,没有层被访问,maxDepth 应该还是未初始化状态。
  • 如果用 int maxDepth = 0;,说明认为至少访问了一层深度(深度0)
  • 代码循环从 0maxDepth,会执行一次。
  • 但实际上没有节点,也没往map中放任何数据,所以map.get(0)会返回null,结果列表加了一个null
  • 导致与预期的空列表([])不符。

方法二:广度优先搜索(queue)

class Solution {public List<Integer> rightSideView(TreeNode root) {Map<Integer, Integer> rightmostValueAtDepth = new HashMap<Integer, Integer>();int max_depth = -1;Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();Queue<Integer> depthQueue = new LinkedList<Integer>();nodeQueue.add(root);depthQueue.add(0);while (!nodeQueue.isEmpty()) {TreeNode node = nodeQueue.remove();int depth = depthQueue.remove();if (node != null) {// 维护二叉树的最大深度max_depth = Math.max(max_depth, depth);// 由于每一层最后一个访问到的节点才是我们要的答案,因此不断更新对应深度的信息即可rightmostValueAtDepth.put(depth, node.val);nodeQueue.add(node.left);nodeQueue.add(node.right);depthQueue.add(depth + 1);depthQueue.add(depth + 1);}}List<Integer> rightView = new ArrayList<Integer>();for (int depth = 0; depth <= max_depth; depth++) {rightView.add(rightmostValueAtDepth.get(depth));}return rightView;}
}

为什么最后访问到的才是最右边节点?

  • rightmostValueAtDepth.put(depth, node.val); 不断地更新当前深度对应的节点值。
  • 访问顺序是每层从左到右,意味着:
    • 最开始访问的节点会写入该层的值。
    • 后面访问的节点会覆盖之前的值。
    • 因为是从左往右访问,最后访问的节点就是最右节点。
  • 最终 “rightmostValueAtDepth” 保存的,正是每一层的最右边节点值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/82456.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/82456.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/82456.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【R语言科研绘图】

R语言在绘制SCI期刊图像时具有显著优势&#xff0c;以下从功能、灵活性和学术适配性三个方面分析其适用性&#xff1a; 数据可视化库丰富 R语言拥有ggplot2、lattice、ggpubr等专业绘图包&#xff0c;支持生成符合SCI期刊要求的高分辨率图像&#xff08;如TIFF/PDF格式&#…

【Node.js】Web开发框架

个人主页&#xff1a;Guiat 归属专栏&#xff1a;node.js 文章目录 1. Node.js Web框架概述1.1 Web框架的作用1.2 Node.js主要Web框架生态1.3 框架选择考虑因素 2. Express.js2.1 Express.js概述2.2 基本用法2.2.1 安装Express2.2.2 创建基本服务器 2.3 路由2.4 中间件2.5 请求…

PDF 转 JPG 图片小工具:CodeBuddy 助力解决转换痛点

本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 前言 在数字化办公与内容创作的浪潮中&#xff0c;将 PDF 文件转换为 JPG 图片格式的需求日益频繁。无论是学术文献中的图表提取&#xff0c;还是宣传资料的视觉化呈现&am…

Linux 文件系统层次结构

Linux 的文件系统遵循 Filesystem Hierarchy Standard (FHS) 标准&#xff0c;其目录结构是层次化的&#xff0c;每个目录都有明确的用途。以下是 Linux 中部分目录的作用解析&#xff1a; 1. 根目录 / 作用&#xff1a;根目录是整个文件系统的顶层目录&#xff0c;所有其他目…

密码学标准(Cryptography Standards)介绍

密码学标准(Cryptography Standards)是为确保信息安全传输、存储和处理而制定的一系列技术规范和协议,广泛应用于通信、金融、互联网等领域。以下从分类、主流标准、应用场景和发展趋势四个方面进行详细介绍: 一、密码学标准的分类 密码学标准可根据技术原理和应用场景分…

ubuntu 22.04安装和使用docker介绍

docker安装和使用 准备环境常见的docker操作linux系统常用的配置卸载docker 准备环境 本机环境&#xff1a; Linux yz-MS-7E06 6.8.0-59-generic #61~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:03:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux安装依赖软件&#xff1a;…

obsidian 中的查找和替换插件,支持正则

最近用着 obsidian 时&#xff0c;发现想要在当前文档中 查找和替换 内容时&#xff0c;没有自动查找和替换的功能&#xff0c;去插件市场查找也没有发现好用的插件&#xff0c;那就自己写一个吧。 全程用的 AI 来写的&#xff0c;当然&#xff0c;我对 JS/CSS/TypeScript 等没…

针对vue项目的webpack优化攻略

一、开发阶段优化 1. 热更新加速&#xff08;HMR&#xff09; // vue.config.js module.exports {devServer: {hot: true, // 开启热更新injectClient: true, // 自动注入HMR客户端watchOptions: {ignored: /node_modules/, // 忽略node_modules变化aggregateTimeout: 300…

BTC官网关注巨鲸12亿美元平仓,XBIT去中心化交易平台表现稳定

在全球加密货币市场波动加剧的背景下&#xff0c;2025年5月25日传出重磅消息。据今日最新国际报道&#xff0c;知名巨鲸James Wynn完全平仓价值12亿美元的BTC多头仓位&#xff0c;整体盈利约845万美元&#xff0c;此举引发市场广泛关注。与此同时&#xff0c;收益型稳定币市场迎…

在WPF中添加动画背景

在WPF中添加动画背景 在WPF中创建动画背景可以大大增强应用程序的视觉效果。以下是几种实现动画背景的方法&#xff1a; 方法1&#xff1a;使用动画ImageBrush&#xff08;图片轮播&#xff09; <Window x:Class"AnimatedBackground.MainWindow"xmlns"htt…

单点击登录sso实现

一、单点登录&#xff08;SSO&#xff09;是什么&#xff1f; 核心定义 单点登录&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一种身份认证解决方案&#xff0c;允许用户通过一次登录访问多个相互信任的应用系统。其核心逻辑是统一认证中心与分布式会话管理&…

JavaWebsocket-demo

Websocket客户端 pom依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.4.0</version></dependency>客户端代码片段 Component Slf4j public class PositionAlarmL…

Java Collection(集合) 接口

Date: 2025-05-21 20:21:32 author: lijianzhan Java 集合框架提供了一组接口和类&#xff0c;以实现各种数据结构和算法。 以下是关于 Java 集合的核心内容说明&#xff1a; /*** Java Collection Framework 说明&#xff1a;** 在 Java 中&#xff0c;集合&#xff08;Collec…

让MySQL更快:EXPLAIN语句详尽解析

前言 在数据库性能调优中&#xff0c;SQL 查询的执行效率是影响系统整体性能的关键因素之一。MySQL 提供了强大的工具——EXPLAIN 语句&#xff0c;帮助开发者和数据库管理员深入分析查询的执行计划&#xff0c;从而发现潜在的性能瓶颈并进行针对性优化。 EXPLAIN 语句能够模…

Java基础 Day20

一、HashSet 集合类 1、简介 HashSet 集合底层采取哈希表存储数据 底层是HashMap 不能使存取有序 JDK8之前的哈希表是数组和链表&#xff0c;头插法 JDK8之后的哈希表是数组、链表和红黑树&#xff0c;尾插法 2、存储元素 &#xff08;1&#xff09;如果要保证元素的唯…

2505C++,32位转64位

原文 假设有个想要将一个32位值传递给一个带64位值的函数的函数.你不关心高32位的内容,因为该值是传递给回调函数的直通值,回调函数会把它截断为32位值. 因此,你都担心编译器一般生成的将32位值扩展到64位值的那条指令的性能影响. 我怀疑这条指令不是程序中的性能瓶颈. 我想出…

光伏电站及时巡检:守护清洁能源的“生命线”

在“双碳”目标驱动下&#xff0c;光伏电站作为清洁能源的主力军&#xff0c;正以年均20%以上的装机增速重塑全球能源格局。然而&#xff0c;这些遍布荒漠、屋顶的“光伏矩阵”并非一劳永逸的能源提款机&#xff0c;其稳定运行高度依赖精细化的巡检维护。山东枣庄触电事故、衢州…

C++初阶-list的使用2

目录 1.std::list::splice的使用 2.std::list::remove和std::list::remove_if的使用 2.1remove_if函数的简单介绍 基本用法 函数原型 使用函数对象作为谓词 使用普通函数作为谓词 注意事项 复杂对象示例 2.2remove与remove_if的简单使用 3.std::list::unique的使用 …

OpenHarmony平台驱动使用(一),ADC

OpenHarmony平台驱动使用&#xff08;一&#xff09; ADC 概述 功能简介 ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模拟-数字转换器&#xff0c;可将模拟信号转换成对应的数字信号&#xff0c;便于存储与计算等操作。除电源线和地线之外&#…

CSS【详解】弹性布局 flex

适用场景 一维&#xff08;行或列&#xff09;布局 基本概念 包裹所有被布局元素的父元素为容器 所有被布局的元素为项目 项目的排列方向&#xff08;垂直/水平&#xff09;为主轴 与主轴垂直的方向交交叉轴 容器上启用 flex 布局 将容器的 display 样式设置为 flex 或 i…