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: (…

Zookeeper(一):在WSL单机搭建Zookeeper伪集群

目录 Zookeeper1 启动单个Zookeeper实例1.1 下载Zookeeper安装包并解压1.2 添加环境变量1.3 修改默认配置1.4 新建数据存储目录和日志目录1.5 启动Zookeeper1.6 停止Zookeeper 2 搭建Zookeeper集群2.1 新建集群目录2.2 配置环境变量2.3 创建节点目录2.4 修改配置2.5 创建节点ID…

2311skia,05绘制文本

绘画文字 绘画文字主要包括转换编码(主要是中文),解析字形(点线或image)和实际渲染三个步骤.在该过程中,解析字形和实际渲染均是耗时步骤. Skia缓存解析文字的结果.在中文字较多,使用多种字体,绘画风格(粗/斜体)有变化时,该缓存会很大,因此Skia文字,限制了缓存的内存. 1,SkP…

CSIT883系统分析与项目管理——Lecture4重点概念

文章目录 一、前言二、重点概念三、题目分析总结一、前言 这次课程给大家介绍信息收集、建模和工作流与项目范围管理相关的知识与题目。同时这节课还有一个重点内容——活动图,我打算单独写一篇文章进行讲解,感兴趣的同学可以留意一下哦! 二、重点概念 1.工作分解结构(W…

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

渗透测试【一】&#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…

某省交控高速公路分公司高效运维

客户背景与挑战 某省交通控股集团下面有一个高速公路分公司&#xff0c;负责运营和管理该省的高速公路网络。随着IT设备的增加和机房动环设备数量的增长&#xff0c;该公司在跨区域跨网络管理、平台升级和扩容方面遇到了挑战。为了解决这些问题&#xff0c;该公司选择使用监控易…

【挑战业余一周拿证】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;调试和执行按钮…

Java入门基础:浅显易懂 do...while

文章目录 前言一、布尔表达式二、do...while三、语法四、示例 前言 do…while 在开发过程中其实并不常用&#xff0c;95%以上都是用 for 而不是 do…while。因为 do…while 能做的 for 能做&#xff0c;do…while 不能做的 for 也能做。所以对于 do…while 能够看懂代码即可 在…

【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 以往的无监督技能发现方法主要使…

Unity优化——脚本优化策略2

大家好&#xff0c;这里是七七&#xff0c;今天继续来介绍几个Unity脚本优化策略 一、更快的GameObject空引用检查 事实证明&#xff0c;对GameObject执行空引用检查会导致一些不必要的开销。与典型的C#对象相比&#xff0c;GameObject和MonoBehaviour是特殊对象&#xff0c;…

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

城市地下管线是指城市范围内供应水、排放水、燃气等各类管线及其附属设施&#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;存在一个回文序列。 请你返回从根到叶子节点的所有路…