leetcode刷题详解五

117. 填充每个节点的下一个右侧节点指针 II

关键点:先递归右子树

画一下就知道了,画一个四层的二叉树,然后右子树多画几个节点就知道为啥了

Node* connect(Node* root) {if(!root || (!root->left && !root->right)){return root;}if(root->left && root->right){root->left->next = root->right;root->right->next = get_next_node(root);}if(!root->right){cout<<"1"<<endl;root->left->next = get_next_node(root);}if(!root->left){root->right->next = get_next_node(root);}connect(root->right);connect(root->left);return root;}Node* get_next_node(Node* root){while(root->next){if(root->next->left){return root->next->left;}else if(root->next->right){return root->next->right;}root = root->next;}return nullptr;}
114. 二叉树展开为链表

将左子树上的东西都放到右子树上去,递归的写,注意,只关注局部即可。

void flatten(TreeNode* root) {if(!root ){return ;}flatten(root->left);flatten(root->right);//最后处理根节点TreeNode* tmp_right = root->right;root->right = root->left;root->left = nullptr;TreeNode* tmp = root;while(tmp->right){tmp = tmp->right;}tmp->right = tmp_right;
}
654. 最大二叉树
TreeNode constructMaximumBinaryTree([3,2,1,6,0,5]) { // 找到数组中的最大值 TreeNode root = new TreeNode(6); // 递归调用构造左右子树 root.left = constructMaximumBinaryTree([3,2,1]); root.right = constructMaximumBinaryTree([0,5]); return root;}

上面代码就是本体的答题思路。

对于构造二叉树的问题,根节点要做的就是把想办法把自己构造出来

TreeNode* constructMaximumBinaryTree(vector<int>& nums) {int left = 0;int right = nums.size();return build_binary_tree(nums, left, right);}TreeNode* build_binary_tree(vector<int>& nums, int left, int right){//递归结束条件if(left >= right){return nullptr;}int max = INT_MIN;int index = -1;for(int i = left;i < right;i++){if(max < nums[i]){max = nums[i];index = i;}}TreeNode* root = new TreeNode(max);root->left = build_binary_tree(nums, left, index);root->right = build_binary_tree(nums, index + 1, right);return root;}
⭕️105. 从前序与中序遍历序列构造二叉树(★面试常考)

代码思路还是跟654题一模一样,可以说,构造二叉树的题递归代码都差不多!

这道题的思路用一下图片即可说明:

图片 图片

详细思路可以看这里

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(preorder.size() == 0){return nullptr;}return build_tree_instance(preorder, 0, preorder.size(), inorder, 0, inorder.size());}TreeNode* build_tree_instance(vector<int>& preorder, int pre_left, int pre_right,vector<int>& inorder, int in_left, int in_right){if(in_left >= in_right){return nullptr;}int left_count = 0;int index = -1;int root_value = preorder[pre_left];for(int i = in_left;i < in_right; i++){if(root_value == inorder[i]){index = i;break;}}left_count = index - in_left;TreeNode* root = new TreeNode(root_value);root->left = build_tree_instance(preorder,pre_left+1, pre_left+left_count,inorder, in_left, index);root->right = build_tree_instance(preorder,pre_left+left_count+1, pre_right,inorder, index+1, in_right);return root;}
⭕️106. 从中序与后序遍历序列构造二叉树

跟上一题思路一模一样

但是这道题第一次做困了很久,就是边界找不准,一直有问题,一定要好好想想。

主要是前序和后序数组的边界不好找,中序的两道题都一样。

TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if(inorder.size() == 0){return nullptr;}return bulid_tree_instance(inorder, 0, inorder.size(),postorder, 0, postorder.size()); }TreeNode* bulid_tree_instance(vector<int>& inorder, int in_left, int in_right,vector<int>& postorder, int post_left, int post_right){if(in_left >= in_right){return nullptr;}int index = 0;int left_count = 0;int root_val = postorder[post_right-1];for(int i = in_left;i < in_right; i++){if(root_val == inorder[i]){index = i;break;}}left_count = index - in_left;TreeNode* root = new TreeNode(root_val);root->left = bulid_tree_instance(inorder,in_left, index,postorder,post_left, post_left+left_count);root->right = bulid_tree_instance(inorder, index+1, in_right,postorder, post_left+left_count, post_right-1); //post_right -1 这个是最容易被忽视的,后序遍历要看最后一个值return root;}
652. 寻找重复的子树

这道题的思想还是一个:对于树的某一个节点,清楚他要干啥!

所以这道题有两步:①以我自己为根的子树长什么样子。 ②以其他节点为根的子树的样子

以某一个节点为根的子树的样子,很明显就是后序遍历

接着序列化原先的二叉树,对比一下就行

文章参考链接

map<string,int> map_tree;vector<TreeNode*> vec_tree;vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {sqe_tree(root);return vec_tree;}string sqe_tree(TreeNode* root){if(!root){return "#";}string left = sqe_tree(root->left);string right = sqe_tree(root->right);string str_tree = left + "," + right + "," + to_string(root->val);if(map_tree[str_tree] == 1){vec_tree.push_back(root);}//重要map_tree[str_tree]++;return str_tree;}

这道题总结一下,有以下两个点。本题涉及的数据结构知识,本题的细节。

  • 本题的细节

    这道题耗费我较多时间。有几个需要注意的点。

    • 二叉树序列化的方法,需要写一个辅助函数完成,辅助函数的返回值用string,这个需要好好记住。
    • 最开始存储序列化后的字符串用的是set,但我发现一个巨大的问题。即如果有set中重复的被找到,则放到vector中,这本来没什么问题,但是,注意这里面有个坑,即只要重复就放到vector中。这是you逻辑问题的,因为如果一个字符串重复了5次,vector中应该只有一个根节点,但是代码会放4次相同的根节点,这样vector中会出现重复,这是会出错的。所以用map方便。
  • 涉及的数据结构

    stl的关联式容器中有两个大类:set和map。由这两个基本关联式容器衍生出来很多,例如multimap、multiset、unordered_map、unordered_set。

    1. set就是数学上所说的元素的集合,可以理解为键和值完全相等的关联式容器。set会根据各个元素值的大小进行生序排序,底层使用红黑树来实现。值不能重复,由insert保证。
    2. map是由键和值两部分组成的关联式容器。键必须唯一,因此如果遇到有相同键的情况,可以使用[]运算符让值++,比如map[str]++。根据键map会进行生序排序。insert保证了键的唯一性。底层用红黑树实现。
    3. multiset。顾名思义,键(值)可以重复的关联式容器。底层用红黑树实现。
    4. multimap。键可以重复的关联式容器,其他与map都一样。
    5. unordered_set。底层是哈希表,占用空间较多,查找是常数时间。无自动排序功能。
    6. unordered_map。底层是哈希表,占用空间较多,查找是常数时间。无自动排序功能。
968. 监控二叉树
  • 思路:本质上就是节点间信息的交流。那么二叉树有三种信息交流的方式,前序,中序和后序。

    由于我们可以分析,返回最小的摄像头数量,那么我们肯定尽量不在子节点装摄像头,而是在父节点装。因此从子节点往父节点传递信息的方式是后序遍历,我们可以用后序遍历的形式做这道题。

    很自然,每个节点肯定有三种该状态啦:

    • 0表示没有被监控
    • 1表示该节点有摄像头
    • 2表示被监控到了

    然后我们就按照后序遍历,依次传递消息。

    本质上是贪心,因为如果子节点被覆盖了,那么当前父节点就不要设置监视器,这是一条隐形规则。

  • 代码

    class Solution {
    public:int result;int minCameraCover(TreeNode* root) {result = 0;if(bianli(root) == 0){result++;}return result;}int bianli(TreeNode* root){if(root == nullptr){return 2;}int left = bianli(root->left);int right = bianli(root->right);//逻辑部分// 0表示没有被监控// 1表示该节点有摄像头// 2表示被监控到了//①左右节点都被监控了。因为是自下而上,已经被监控了,其父节点就不用摄像头了,父节点就是没被监控if(left == 2 && right ==2){return 0;}//②左右节点至少有一个没被监控。说明父节点要放摄像头if(left == 0 || right == 0){result++;return 1;}//③左右节点至少有一个摄像头,那么父节点会被监控到if(left ==1 || right ==1){return 2;}return -1;}
    

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

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

相关文章

实战oj题——括号匹配问题

前言&#xff1a;前面我们已经做了一些关于顺序表和链表的oj题&#xff0c;今天我们就来解决一些有关于栈和队列的oj题。 我们对这个题看起来毫无头绪&#xff0c;但是我们刚学习了栈&#xff0c;就可以用栈来解决这一类问题&#xff0c;如果我们读取到左括号就入栈&#xff0c…

2023年最新Visual Studio下载安装以及C语言环境搭建教程(含C语言入门教程)

文章目录 写在前面C语言简介Visual Studio简介Visual Studio安装教程 C语言入门Visual Studio使用教程 写在后面 写在前面 2023年最新Visual Studio下载安装以及C语言环境搭建教程来啦&#xff01;一起来看看吧~ C语言简介 C语言是一种高级编程语言&#xff0c;由美国贝尔实…

90. 打家劫舍II (房子围成一圈)

题目 题解 class Solution:def rob(self, nums: List[int]) -> int:def dp(nums: List[int]) -> int:N len(nums)# 定义状态&#xff1a;dp[i]表示从第i个房屋开始偷窃&#xff0c;能够偷到的最高金额dp [0 for i in range(N)]for i in range(N-1, -1, -1):if i N-1:…

uiautomator2 无法连接 ATX-Agent

最近需要写个安卓自动项目&#xff0c;本身不想用appium 。主要是appium需要安装的依赖太多&#xff0c;一单换个环境又要配置新的环境。但是ATX-Agent装好之后怎么都连接不是。 报错信息如下&#xff1a; .........省略............ uiautomator2.exceptions.GatewayError: (…

渗透测试【一】:渗透测试常见问题

渗透测试【一】&#xff1a;渗透测试常见问题 1、问题清单2、问题现象及解决办法2.1、点击劫持2.2、用户枚举2.3、Springboot未授权访问2.4、Swagger未授权访问2.5、Host头注入2.6、任意文件上传2.7、敏感路径泄露2.8、跨域资源共享2.9、Spring Cloud Gateway RCE2.10、Content…

【挑战业余一周拿证】CSDN官方课程目录

一、亚马逊云科技简介 二、在云中计算 三、全球基础设施和可靠性 四、联网 五、存储和数据库 六、安全性 七、监控和分析 八、定价和支持 九、迁移和创新 十、云之旅 关注订阅号 CSDN 官方中文视频&#xff08;免费&#xff09;&#xff1a;点击进入 一、亚马逊云科…

女生儿童房装修:原木上下铺搭配粉色调。福州中宅装饰,福州装修

你是否正在为女生儿童房的装修而发愁呢&#xff1f;该如何让房间既适合孩子生活&#xff0c;又能够满足日常学习的需要呢&#xff1f;这里有一个精美的装修案例&#xff0c;或许能够为你提供一些灵感。 1️⃣ 原木上下铺 房间的上下铺采用了原木色调&#xff0c;带来了自然、温…

STM32 F1 串口空闲中断 + DMA实现数据发送

DMA实现数据发送 文章目录 DMA实现数据发送前言一、DMA二、代码编写1.DMA2.USART3.main 前言 当你遇到通信数据量大的时候&#xff0c;可以使用 空闲中断 DMA 的方案来减轻 CPU 的压力。 或者 在进行stm32开发时&#xff0c;有时会遇到这种情况&#xff1a;需要在设备间进行数…

1.1 C语言之入门:使用Visual Studio Community 2022运行hello world

1.1 使用Visual Studio Community 2022运行c语言的hello world 一、下载安装Visual Studio Community 2022 与 新建项目二、编写c helloworld三、编译、链接、运行 c helloworld1. 问题记录&#xff1a;无法打开源文件"stdio.h"2. 问题记录&#xff1a;调试和执行按钮…

【Linux】bash 终端指令

进程 $ ps aux | grep pwd work 63317 0.0 0.0 51192 612 pts/9 S 14:22 0:00 grep /home/work/search/1000000.dyenv-user-diaoyan-baiseCliPlus-baisePlus-195522.diaoyan.yq/ala-ac/output_root端口 查看本机端口开放情况 netstat -tln | grep :31 tcp …

Unsupervised Skill Discovery via Recurrent Skill Training论文笔记

Zheyuan Jiang, Jingyue Gao, Jianyu Chen (2022). Unsupervised Skill Discovery via Recurrent Skill Training. In Conference on Neural Information Processing Systems (NeurIPS), 2022. 通过循环技能训练发现无监督技能 1、Motivation 以往的无监督技能发现方法主要使…

可燃气体监测仪助力燃气管网安全监测,效果一览

城市地下管线是指城市范围内供应水、排放水、燃气等各类管线及其附属设施&#xff0c;它们是保障城市正常运转的重要基础设施且影响着城市生命线。其中燃气引发的事故近些年不断增加&#xff0c;由于燃气管线深埋地下环境复杂&#xff0c;所以仅仅依赖人工巡查难以全面有效地防…

17. Python 数据库操作之MySQL和SQLite实例

目录 1. 简介2. 使用PyMySQL2. 使用SQLite 1. 简介 数据库种类繁多&#xff0c;每种数据库的对外接口实现各不相同&#xff0c;为了方便对数据库进行统一的操作&#xff0c;大部分编程语言都提供了标准化的数据库接口&#xff0c;用户不需要了解每种数据的接口实现细节&#x…

【每日一题】1457. 二叉树中的伪回文路径-2023.11.25

题目&#xff1a; 1457. 二叉树中的伪回文路径 给你一棵二叉树&#xff0c;每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的&#xff0c;当它满足&#xff1a;路径经过的所有节点值的排列中&#xff0c;存在一个回文序列。 请你返回从根到叶子节点的所有路…

Re55:读论文 Entities as Experts: Sparse Memory Access with Entity Supervision

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;Entities as Experts: Sparse Memory Access with Entity Supervision 模型名称&#xff1a;Entities as Experts (EaE) ArXiv网址&#xff1a;https://arxiv.org/abs/2004.07202 本文…

人工智能基础_机器学习050_对比sigmoid函数和softmax函数的区别_两种分类器算法的区别---人工智能工作笔记0090

可以看到最上面是softmax的函数对吧,但是如果当k = 2 那么这个时候softmax的函数就可以退化为sigmoid函数,也就是 逻辑斯蒂回归了对吧 我们来看一下推导过程,可以看到上面是softmax的函数 可以看到k=2 表示,只有两个类别对吧,两个类别的分类不就是sigmoid函数嘛对吧,所以说 …

ubuntu 安装 jetbrains-toolbox

ubuntu 安装 jetbrains-toolbox 官网下载 jetbrains-toolbox jetbrains 官网 jetbrains 官网&#xff1a;https://www.jetbrains.com/ jetbrains-toolbox 官网下载页面 在下载页面点击 Download 安装 jetbrains-toolbox 解压 jetbrains-toolbox 安装包 到指定目录 本案例将…

STM32 默认时钟更改 +debug调试

STM32时钟 文章目录 STM32时钟前言一、修改系统时钟二、DEBUG 前言 为什么我们要改STM32的时钟呢&#xff0c;打个比方在做SPI驱动的时候&#xff0c;需要16M的时钟&#xff0c;但是stm32默认是72的分频分不出来&#xff0c;这个时候我们就要改系统时钟了&#xff0c;那么怎么…

[科普] 无刷直流电机驱动控制原理图解

Title: [科普] 无刷直流电机驱动控制原理图解 文章目录 I. 引言II. 直流电机的原理1. 有刷直流电机和无刷直流电机的区别2. 有刷直流电机的运行原理3. 既是电动机又是发电机 III. 无刷直流电机的原理1. 无刷直流电机与永磁同步电机的区别2. 无刷直流电机的换向控制原理3. 无刷直…

python 笔记 根据用户轨迹+基站位置,估计基站轨迹+RSRP

1 问题描述 已知用户实际的轨迹&#xff0c;和基站的位置&#xff0c;能不能得到用户所连接的基站&#xff0c;以及基站的信号强度RSRP&#xff1f; 1.1 几个假设 这里我们做几个假设&#xff1a; 每个用户有80%的概率连接最近的基站&#xff0c;有20%的概率选择其他的基站连…