codetop标签树刷题(二)!!暴打面试官!!!!

个人复习用

  • 1.二叉搜索树中第k小的元素
  • 2.删除给定值的叶子节点
  • 3.把二叉搜索树转换为累加树
  • 4.合并二叉树
  • 5.翻转二叉树
  • 6.二叉树中所有距离为k的节点
  • 7.路径总和II
  • 8.寻找重复的子树
  • 9.二叉树的序列化和反序列化

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

给定二叉搜索树的根节点root,和一个整数k,设计一个算法查找其中第k小的元素(从1开始计数)
在这里插入图片描述
BST 的中序遍历结果是有序的(升序),所以用一个外部变量记录中序遍历结果第 k 个元素即是第 k 小的元素。

class Solution {
private:int res = 0;int rank = 0;void traverse(TreeNode* root, int k){if(root == nullptr) return;traverse(root->left, k);//中序位置rank ++;if(rank == k){res = root->val;return;}traverse(root->right, k);}
};
public:int kthSmallest(TreeNode* root, int k) {traverse(root, k);return res;
}

2.删除给定值的叶子节点

给你一棵以 root 为根的二叉树和一个整数 target ,请你删除所有值为 target 的 叶子节点 。

注意,一旦删除值为 target 的叶子节点,它的父节点就可能变成叶子节点;如果新叶子节点的值恰好也是 target ,那么这个节点也应该被删除。

也就是说,你需要重复此过程直到不能继续删除。

遍历所有叶子节点,然后判断是否需要删除即可,删除叶子节点也非常简单,return null让父节点接受即可,难点在于删除操作是循环的,一直删到叶子结点不存在target为止。
这里涉及到后序遍历,一个节点在后序位置接受左右子树的返回值,才能知道自己的叶子节点是否都被删除掉了,以此来判断自己是不是变成了叶子节点

class Solution {
public:TreeNode* removeLeafNodes(TreeNode* root, int target) {if(root == nullptr) return nullptr;// 如果左右子节点需要被删除,先递归删除它们root->left = removeLeafNodes(root->left, target);root->right = removeLeafNode(root->right, target); // 后序遍历位置,此时节点 root 直到自己是否需要被删除//如果当前节点是一个叶子节点并且其值等于 target,则通过返回 nullptr 来告诉调用它的父节点函数,这个节点应该被删除。//这意味着在父节点中,指向这个被删除节点的指针(left 或 right)将被设置为 nullptr。if(root->val == target && root->left == nullptr && root->right == nullptr)return root;}
};

3.把二叉搜索树转换为累加树

给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树,使每个节点node的新值等于原树种大于或等于node.val的值之和。
在这里插入图片描述
求树中大于等于该节点值的所有节点的总和
8,8+7=15,15+6=21,21+5=26,右中左

class Solution {
public:int sum = 0;TreeNode* convertBST(TreeNode* root) {if(root == nullptr) return nullptr;convertBST(root->right);root->val += sum;sum = root->val;convertBST(root->left);return root;}
};

4.合并二叉树

给你两棵二叉树root1和root2。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。
合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。
在这里插入图片描述
可以看做是在遍历root1这一棵二叉树,顺便把root2的节点合并过来。

class Solution {
public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if(root1 == nullptr) return root2;if(root2 == nullptr) return root1;root1->val += root2->val;root1->left = mergeTrees(root1->left, root2->left);root1->right = mergeTrees(root1->right, root2->right);return root1;}
};    

5.翻转二叉树

给你一棵二叉树的根节点,翻转这棵二叉树,并返回其根节点。
在这里插入图片描述

class Solution {
public:TreeNode* invertTree(TreeNode* root) {if(root == nullptr){return nullptr;}invertTree(root->left);invertTree(root->right);TreeNode* tmp = root->right;root->right = root->left;root->left = tmp;return root;}
};

6.二叉树中所有距离为k的节点

给定一个二叉树,具有根节点root,一个目标节点target,和一个整数值k,返回到目标节点target距离为k的所有节点的值的数组。
其中树上所有节点的值val是不同的
在这里插入图片描述
parent来记录当前节点

class Solution {
private:void traverse(TreeNode* root, TreeNode* parentNode){if(root == nullptr) return;parent[root->val] = parentNode;traverse(root->left, root);traverse(root->right, root);}
public:unordered_map<int, TreeNode*> parent;vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {traverse(root, nullptr);queue<TreeNode*> q;q.push(target);unordered_set<int> visited;visited.insert(target->val);int dist = 0;vector<int> res;while(!q.empty()){int size = q.size();for(int i = 0; i < size; i ++){TreeNode* cur = q.front();q.pop();if(dist == k){res.push_back(cur->val);}//向父节点,左孩子节点,右孩子节点三个方向扩散TreeNode* parentNode = parent[cur->val];if(parentNode != nullptr && visited.find(parentNode->val) == visited.end()){visited.insert(parentNode->val);q.push(parentNode);}if(cur->left != nullptr && visited.find(cur->left->val) == visited.end()){visited.insert(cur->left->val);q.push(cur->left);}if(cur->right != nullptr && visited.find(cur->right->val) == visited.end()){visited.insert(cur->right->val);q.push(cur->right);}}dist ++;}return res;}
};	

7.路径总和II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

遍历的思维很简单,只要遍历一遍二叉树,就可以把所有符合条件的路径找出来。为了维护经过的路径,在进入递归的时候要在 path 列表添加节点,结束递归的时候删除节点。

class Solution {
private:vector<vector<int>> res;void traverse(TreeNode* root, vector<int> path, int targetSum){if(root == nullptr) return;int remain = targetSum - root->val;//找到了一条路径if(root->left == nullptr && root->right == nullptr){if(remain == 0){path.push_back(root->val);res.push_back(path);path.pop_back();}return;//继续找}//维护路径列表path.push_back(root->val);traverse(root->left, path, remain);path.pop_back();path.push_back(root->val);traverse(root->right, path, remain);path.pop_back();}
public:vector<vector<int>> pathSum(TreeNode* root, int targetSum) {if(root == nullptr) return res;traverse(root, vector<int>(), targetSum);return res;}
};

8.寻找重复的子树

给你一棵二叉树的根节点 root ,返回所有 重复的子树 。
对于同一类的重复子树,你只需要返回其中任意 一棵 的根结点即可。
如果两棵树具有 相同的结构 和 相同的结点值 ,则认为二者是 重复 的。
在这里插入图片描述
如果想知道以自己为根的子树是不是重复的,是否应该被加入结果列表中,需要知道什么信息?上面的的[2, 4]其实是返回了以2为根节点的TreeNode型
需要知道以下两点

1、以我为根的这棵二叉树(子树)长啥样?-> 需要在后序的位置进行操作

2、以其他节点为根的子树都长啥样?-> 前序后序层序都可以反映二叉树的结构(中序不行),所以可以将二叉树序列化

class Solution {
private:vector<TreeNode*> res;unordered_map<string, int> subTree;string serialize(TreeNode* root){if(root == nullptr) return "#";string left = serialize(root->left);string right = serialize(root->right);string myself = left + ',' + right + ',' + to_string(root->val);int freq = subTree[myself];if(freq == 1){res.push_back(root);}subTree[myself]++;return myself;//随便返回的,需要一个返回值}
public:vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {serialize(root);return res;}
};

9.二叉树的序列化和反序列化

序列化和39是一个意思,反序列化就是给一串string字符串,将其还原成树。

什么样的序列化数据可以反序列化出唯一的一颗二叉树?只要给了空指针信息,前后序层序就可以缺点唯一的二叉树
代码以前序为例

class Codec {
public:// Encodes a tree to a single string.string serialize(TreeNode* root) {if (!root) return "#";return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right);}// Decodes your encoded data to tree.TreeNode* deserialize(string data) {vector<string> nodes;string cur = "";//过滤掉逗号for (char c : data) {if (c == ',') {nodes.push_back(cur);cur = "";} else {cur += c;}}if (!cur.empty()) nodes.push_back(cur); // Add the last nodeint index = 0;return deserialize(nodes, index);}TreeNode* deserialize(vector<string>& nodes, int& index) {if (index >= nodes.size() || nodes[index] == "#") {index++;return nullptr;}TreeNode* root = new TreeNode(stoi(nodes[index++]));root->left = deserialize(nodes, index);root->right = deserialize(nodes, index);return root;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【一起学NLP】Chapter3-使用神经网络解决问题

目录 使用神经网络解决问题Tip:数据集划分学习使用的代码Tip:epochTip:数据打乱Trainer类Tip-高速化计算 使用神经网络解决问题 import sys sys.path.append(..) # 为了引入父目录的文件而进行的设定 from dataset import spiral import matplotlib.pyplot as pltx,t spiral.…

【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象

文章目录 请求1. 传递单个参数注意事项1 . **正常传递参数**2 . **不传递 age 参数**3 . **传递参数类型不匹配** 2. 传递多个参数3. 传递对象 请求 访问不同的路径&#xff0c;就是发送不同的请求。在发送请求时&#xff0c;可能会带一些参数&#xff0c;所以学习 Spring 的请…

传奇GOM引擎架设好进游戏后提示请关闭非法外挂,重新登录,如何处理?

今天在架设一个GOM引擎的版本时&#xff0c;进游戏之后刚开始是弹出一个对话框&#xff0c;提示请关闭非法外挂&#xff0c;重新登录&#xff0c;我用的是绿盟登陆器&#xff0c;同时用的也是绿盟插件&#xff0c;刚开始我以为是绿盟登录器的问题&#xff0c;于是就换成原版gom…

如何构建LSTM神经网络模型

一、了解LSTM 1. 核心思想 首先&#xff0c;LSTM 是 RNN&#xff08;循环神经网络&#xff09;的变体。它通过引入细胞状态 C(t) 贯穿于整个网络模型&#xff0c;达到长久记忆的效果&#xff0c;进而解决了 RNN 的长期依赖问题。 2. 思维导图 每个LSTM层次都有三个重要的门结构…

VMware ESXi更改https的TLS协议版本

简要概述 TLS 1.0 和 1.1 是已弃用的协议&#xff0c;具有广为人知的缺点和漏洞。应在所有接口上启用 TLS 1.2&#xff0c;并在支持的情况下禁用 SSLv3、TL 1.1 和 1.0。强制要求 TLS 1.2 可能会破坏 vSphere 的第三方集成和加载项。在实施 TLS 1.2 后仔细测试这些集成&#x…

maven指定模块快速打包idea插件Quick Maven Package

问题背景描述 在实际开发项目中&#xff0c;我们的maven项目结构可能不是单一maven项目结构&#xff0c;项目一般会用parent方式将各个项目进行规范&#xff1b; 随着组件的数量增加&#xff0c;就会引入一个问题&#xff1a;我们只想打包某一个修改后的组件A时就变得很不方便…

C++ 算法学习——1.8 悬线法

1.问题引入&#xff1a;对于一个矩形图&#xff0c;图中放置着不少障碍&#xff0c;要求出最大的不含障碍的矩形。 2.分析&#xff1a;显然一个极大矩形是左右上下都被障碍挡住&#xff0c;无法再扩大的矩形&#xff0c;此时障碍也包括边界。 3.方法&#xff1a;悬线法考虑以…

01 从0开始搭建django环境

1 安装相关版本的django&#xff0c;这里&#xff0c;我以5.1.1为例子 pip3 install django5.1.1 (.venv) D:\DjangoCode\MS>pip3 install django5.1.1 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting django5.1.1Using cached https://pypi.t…

STM32定时器(TIM)

目录 一、概述 二、定时器的类型 三、时序 四、定时器中断基本结构 五、定时器定时中断代码 六、定时器外部时钟代码 一、概述 TIM(Timer)定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基…

TM1618数码管控制芯片使用共阳极数码管过程中的问题和解决办法

控制芯片的基本了解 相比于不用控制芯片的电路&#xff1a;这里带2根电源线和3个信号线&#xff0c;共使用了5根线&#xff0c;但可以控制4个8段数码管显示。若是电路直接控制4个8段数码管需要84113个接口&#xff0c;这对于MCU的珍贵引脚简直是浪费。 这里不会出现余晖效应也…

Python编程常用的35个经典案例

Python 的简洁和强大使其成为许多开发者的首选语言。本文将介绍35个常用的Python经典代码案例。这些示例覆盖了基础语法、常见任务、以及一些高级功能。 1.列表推导式 这个例子展示了列表推导式&#xff0c;用于生成FizzBuzz序列。 fizz_buzz_list ["FizzBuzz" i…

ultralytics yolo pose 示例:加载官方pose模型进行推理

Ultralytics YOLO 是计算机视觉和 ML 领域专业人士的高效工具。 安装 ultralytics 库&#xff1a; pip install ultralytics 官方YoLo Pose 模型列表信息&#xff1a; 实现代码如下&#xff1a; from ultralytics import YOLO import cv2 # Load a model ckpt_dir "…

HTB:Ignition[WriteUP]

目录 连接至HTB服务器并启动靶机 1.Which service version is found to be running on port 80? 2.What is the 3-digit HTTP status code returned when you visit http://{machine IP}/? 3.What is the virtual host name the webpage expects to be accessed by? 4.…

详细解释:前向传播、反向传播等

详细解释:前向传播、反向传播等 在机器学习和深度学习中,**前向传播(Forward Propagation)和反向传播(Backward Propagation)**是训练神经网络的两个核心过程。理解这两个概念对于掌握神经网络的工作原理、优化方法以及模型微调技术(如LoRA、P-tuning等)至关重要。以下…

机器人技术基础(1-3章坐标变换)

位置矢量的意思是B坐标系的原点O相对于A坐标系的平移变换后的矩阵&#xff1a; 齐次坐标最后一个数表示缩放倍数&#xff1a; 左边的是T形变换矩阵&#xff0c;右边的是需要被变换的矩阵&#xff1a;T形变换矩阵的左上角表示旋转&#xff0c;右上角表示平移&#xff0c;左下角最…

好用且不伤眼镜的超声波清洗机排名!谁才是清洁小能手?

对于经常佩戴眼镜的人来说&#xff0c;眼镜的日常清洁保养极为关键。传统清洁方式可能导致镜片刮花和残留污渍&#xff0c;鉴于此&#xff0c;眼镜专用的超声波清洗机应运而生&#xff0c;利用超声振动技术深入微细缝隙&#xff0c;彻底扫除污垢与油脂&#xff0c;保护镜片免受…

JavaEE: 数据链路层的奇妙世界

文章目录 数据链路层以太网源地址和目的地址 类型数据认识 MTU 数据链路层 以太网 以太网的帧格式如下所示: 源地址和目的地址 源地址和目的地址是指网卡的硬件地址(也叫MAC地址). mac 地址和 IP 地址的区别: mac 地址使用6个字节表示,IP 地址4个字节表示. 一般一个网卡,在…

Unity3D 单例模式

Unity3D 泛型单例 单例模式 单例模式是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c;提供访问实例的全局节点。 通常会把一些管理类设置成单例&#xff0c;例如 GameManager、UIManager 等&#xff0c;可以很方便地使用这些管理类单例&#xff0c;…

BM1 反转链表

要求 代码 /*** struct ListNode {* int val;* struct ListNode *next;* };*/ /*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*** param head ListNode类* return ListNode类*/ struct ListNode* ReverseList(struct …

从零开始讲PCIe(10)——事务层介绍

一、事务层概述 事务层在响应软件层的请求时&#xff0c;会生成出站数据包。同时&#xff0c;它也会检查入站数据包&#xff0c;并将其中包含的信息传递到软件层。事务层支持非发布事务的分割事务协议&#xff0c;能够将入站的完成数据包与之前传输的非发布请求相关联。该层处理…