Leetcode 3.15

Leetcode hot100

  • 二叉树
    • 1.二叉搜索树中第K小的元素
    • 2.二叉树展开为链表
    • 3.从前序与中序遍历序列构造二叉树

二叉树

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

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

最重要的知识点:二叉树搜索树的中序遍历是升序的
方法一:我们只需存储升序遍历,返回升序遍历的结果即可。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<int> ans;int kthSmallest(TreeNode* root, int k) {dfs(root);return ans[k - 1];}void dfs(TreeNode* root) {if (root == nullptr) return;dfs(root->left);ans.push_back(root->val);dfs(root->right);    }
};

改进:我们还可以在找到答案后停止,不需要遍历整棵树。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int ans;int kthSmallest(TreeNode* root, int k) {dfs(root, k);return ans;}void dfs(TreeNode* root, int &k) {if (root == nullptr) return;dfs(root->left, k);if (--k == 0) {ans = root->val;return;}dfs(root->right, k);    }
};

2.二叉树展开为链表

二叉树展开为链表
题目要求展开后与先序遍历相同,那么可以按照先序遍历再更改链表,在前序遍历结束之后更新每个节点的左右子节点的信息,找到前后元素在二叉树当中的位置,将二叉树展开为单链表。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:void flatten(TreeNode* root) {vector<TreeNode*> ans;dfs(root, ans);for (int i = 1; i < ans.size(); i++) {//前一个节点auto *pre = ans.at(i - 1);//当前节点auto *cur = ans.at(i);pre->left = nullptr;pre->right = cur; }}void dfs(TreeNode* root, vector<TreeNode*> &ans) {if (root == nullptr) return;ans.push_back(root);dfs(root->left, ans);dfs(root->right, ans);      }
};

思路二:更便捷的递归
参考
这个问题其实是分为三步:

  • 首先将根节点的左子树变成链表
  • 其次将根节点的右子树变成链表
  • 最后将变成链表的右子树放在变成链表的左子树的最右边

这就是一个递归的过程,递归的一个非常重要的点就是:不去管函数的内部细节是如何处理的,我们只看其函数作用以及输入与输出。对于函数flatten来说:

函数作用:将一个二叉树,原地将它展开为链表
输入:树的根节点
输出:无

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:void flatten(TreeNode* root) {if (root == nullptr) return;//展开左子树为链表flatten(root->left);//展开子树为链表flatten(root->right);auto l = root->left;auto r = root->right;//左子树置空root->left = nullptr;//左子树移动到右子树root->right = l;//指针指向右子树最后一个节点while (root->right != nullptr) root = root->right;//指向右子树root->right = r;}
};

3.从前序与中序遍历序列构造二叉树

从前序与中序遍历序列构造二叉树
根据前序和中序遍历我们可以确定二叉树的根节点,左子树和右子树,不断递归得到结果。比较复杂的是确定左右子树的边界。借助map来快速确定元素在inorder中的位置,这副图中的边界位置建议仔细推导。
需要注意的点:前序遍历中,左子树的右边界 需要借助 中序遍历中 左子树的个数 来辅助确定。
在这里插入图片描述

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int n = preorder.size();if (!n) return nullptr;unordered_map<int, int> mp;for (int i = 0; i < n; i++) {mp[inorder[i]] = i;}return dfs(preorder, 0, n - 1, mp, 0, n - 1);}TreeNode* dfs(vector<int>& preorder, int preleft, int preright,unordered_map<int, int>& mp, int inleft, int intright) {if (preright < preleft || inleft > intright) return nullptr;TreeNode* ans = new TreeNode(preorder[preleft]);ans->left = dfs(preorder, preleft + 1, mp[preorder[preleft]] + preleft - inleft, mp, inleft, mp[preorder[preleft]] - 1);ans->right = dfs(preorder, mp[preorder[preleft]] + preleft - inleft + 1, preright, mp, mp[preorder[preleft]] + 1, intright);return ans;}};

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

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

相关文章

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ListItemGroup)

该组件用来展示列表item分组&#xff0c;宽度默认充满List组件&#xff0c;必须配合List组件来使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件的父组件只能是List。 使用说明 当List…

Docker使用(四)Docker常见问题分析和解决收集整理

Docker使用(四)Docker常见问题分析和解决收集整理 五、常见问题 1、 启动异常 【描述】&#xff1a; 【分析】&#xff1a;[rootlocalhost ~]# systemctl status docker 【解决】&#xff1a; &#xff08;1&#xff09;卸载后重新安装&#xff0c;不能解决这个问题。 …

Android cmdline tools安装

打开AS 进入SDK Tools 看到了吗?那个打着勾的就是

如何将图片无损放大?

如何将图片无损放大&#xff1f; 在处理图片时&#xff0c;我们经常会遇到需要放大图像而又不损失图像质量的情况。这种操作被称为“图片无损放大”&#xff0c;它可以帮助我们保持图像的清晰度和细节&#xff0c;同时满足对更大尺寸图像的需求。传统的图像放大方法往往会导致…

重要表格比较多 不想被别人查阅 怎样批量加密?excel批量加密

批量给Excel工作表加密是一个既实用又具挑战性的任务。对于需要在多个工作表中保护敏感信息的用户来说&#xff0c;掌握这一技能尤为重要。下面&#xff0c;我们将详细介绍如何批量给Excel工作表加密 首先&#xff0c;我们要选择合适的加密方法&#xff0c;在这里小编给大家推荐…

ASP.NET-WebFoms常见前后端交互方式

在 ASP.NET Web Forms 中&#xff0c;实现前后端交互是开发 Web 应用程序的重要部分。通过合适的数据传递方式&#xff0c;前端页面能够与后端进行有效的通信&#xff0c;并实现数据的传递、处理和展示。本文介绍了ASP.NET Web Forms开发中常见的前后端交互方式&#xff0c;包括…

Reactor,Proactor,Actor网络模型

Reactor&#xff0c;Proactor&#xff0c;Actor_reactor actor-CSDN博客 Actor模型是一种并发编程模型&#xff0c;它定义了计算单元的行为&#xff0c;这些计算单元被称为Actors。Actors通过消息传递进行通信&#xff0c;它们之间相互隔离&#xff0c;不共享内存。Actors…

Spring MVC(一)— DispatcherServlet

DispatcherServlet 是Spring MVC框架的HTTP 请求处理器的中央调度器。它具有以下的功能&#xff1a; 1&#xff09;基于IoC容器JavaBean配置机制。 2&#xff09;使用HandlerMappingl来实现请求到处理器的路由映射。 3&#xff09;使用HandlerAdapter 来处理不同的处理器。 …

Go 构建高效的二叉搜索树联系簿

引言 树是一种重要的数据结构&#xff0c;而二叉搜索树&#xff08;BST&#xff09;则是树的一种常见形式。在本文中&#xff0c;我们将学习如何构建一个高效的二叉搜索树联系簿&#xff0c;以便快速插入、搜索和删除联系人信息。 介绍二叉搜索树 二叉搜索树是一种有序的二叉…

探索SOCKS5代理、代理IP、HTTP与网络安全

在这个数字化时代&#xff0c;网络安全已成为我们日常生活中不可或缺的一部分。作为一名软件工程师&#xff0c;深入理解网络通信的核心技术&#xff0c;如SOCKS5代理、代理IP、HTTP协议&#xff0c;以及它们在网络安全中的应用&#xff0c;对于设计和实施安全的网络应用至关重…

uni-app 安卓手机判断是否开启相机相册权限

// 安卓相机权限 androidCameraPermiss(index){ plus.android.requestPermissions([android.permission.CAMERA],(e) > { if (e.deniedAlways.length > 0) { this.androidAuthCamera false …

【自动驾驶可视化工具】

自动驾驶可视化工具 自动驾驶可视化工具1.百度Apollo的Dreamview:2.Cruise的Worldview:3.Uber的AVS:4.Fglovex Studio: 自动驾驶可视化工具 介绍一下当前主流的自动驾驶可视化工具。 1.百度Apollo的Dreamview: Dreamview是百度Apollo平台开发的一种可视化工具&#xff0c;用…

使用Spark清洗统计业务数据并保存到数据库中

1、打开前面创建的项目“BigData-Etl-KongGuan”&#xff0c;创建一些数据库访问的工具类和辅助类。 1&#xff09;打开SpringBoot项目&#xff1a;BigData-Etl-KongGuan 2&#xff09;创建数据库访问的工具类和辅助类&#xff1a; com.qrsoft.etl.dao.IBaseDao数据库访问的通…

基于正点原子潘多拉STM32L496开发板的简易示波器

一、前言 由于需要对ADC采样性能的评估&#xff0c;重点在于对原波形的拟合性能。 考虑到数据的直观性&#xff0c;本来计划采集后使用串口导出&#xff0c;并用图形做数据拟合&#xff0c;但是这样做的效率低下&#xff0c;不符合实时观察的需要&#xff0c;于是将开发板的屏幕…

【DataWhale学习笔记】使用AgentScope调用同义倩文大模型

AgentScope AgentScope介绍 AgentScope是一款全新的Multi-Agent框架&#xff0c;专为应用开发者打造&#xff0c;旨在提供高易用、高可靠的编程体验&#xff01; 高易用&#xff1a;AgentScope支持纯Python编程&#xff0c;提供多种语法工具实现灵活的应用流程编排&#xff…

部署prometheus+Grafana可视化仪表盘监控服务

一、部署prometheus及监控仪表盘 简介 Prometheus是开源监控报警系统和时序列数据库(TSDB)。 Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提供对应的HTTP接口就可以接入监控&#xff0c;输出被监控组件信息的HTTP接口被叫做expo…

Node.js(1)

跨平台的node.js运行环境&#xff0c;使开发者可以搭建服务器端的js应用程序 它可以编写服务器端程序&#xff1b; 编写数据接口&#xff1b;提供网页资源浏览功能 前端工程化&#xff1a;开发集成的所有工具和技术 与浏览器环境的区别 node.js环境中没有DOM和BOM fs模块-读…

使用Jackson进行 JSON 序列化和反序列化

在Spring应用程序中&#xff0c;您可以通过Maven添加Jackson依赖&#xff0c;并创建一个工具类来封装对象的序列化和反序列化方法。以下是详细步骤&#xff1a; 1. 引入 Jackson 依赖 如果使用 Maven&#xff0c;您可以在 pom.xml 文件中添加以下依赖&#xff1a; <depend…

5 个适用于 Windows 10 和 11 的最佳 PDF 转 Word 转换器

PDF 文件是共享文档的首选格式&#xff0c;但是此类文件存在一些限制&#xff0c;导致难以修改或编辑。因此&#xff0c;您可能会发现自己正在寻找一种将 PDF 文件转换为 Word 或其他可编辑格式的方法。 有许多不同的 PDF 转换器&#xff0c;每种转换器提供的功能略有不同。本…

多人聊天室 (epoll - Linux网络编程)

文章目录 零、效果展示一、服务器代码二、客户端代码三、知识点1.bind() 四、改进方向五、跟练视频 零、效果展示 一个服务器作为中转站&#xff0c;多个客户端之间可以相互通信。至少需要启动两个客户端。 三个客户端互相通信 一、服务器代码 chatServer.cpp #include <…