leetcode刷题详解五

news2024/11/28 20:35:16
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.coloradmin.cn/o/1256668.html

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

相关文章

针对操作系统漏洞的反馈方法

一、针对操作系统漏洞的反馈方法 漏洞扫描指基于漏洞数据库&#xff0c;通过扫描等手段对指定的远程或者本地计算机系统的安全脆弱性进行检测&#xff0c;发现可利用漏洞的一种安全检测&#xff08;渗透攻击&#xff09;行为。在进行漏洞扫描后&#xff0c;需先确定哪些是业务…

二叉树:leetcode1457. 二叉树中的伪回文路径

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

SSD FTL 映射管理

映射的种类 根据映射粒度的不同分为如下几种 1.块映射 一个逻辑块&#xff08;logical block&#xff09;映射到一个闪存物理块(physical block) 优点是&#xff1a;映射表需要空间小&#xff0c;对大Block size顺序读写&#xff0c;但是对小尺寸数据的写入性能很差。因为即使…

基于改进莱维飞行和混沌映射粒子群优化算法(LPSO)-BP神经网络的时间序列预测模型

基于改进莱维飞行和混沌映射粒子群优化算法(LPSO)原理&#xff1a; 通过引入混沌映射机制&#xff0c;对其群体进行初始化&#xff0c;增加粒子群个体的多样性&#xff1b;然后在粒子群个体的位置更新公式上引入改进的莱维飞行机制&#xff0c;提高搜索精度&#xff0c;帮助粒…

重庆数字孪生技术推进制造业升级,工业物联网可视化应用加速

重庆数字孪生、5G、人工智能、物联网、大数据等新一代信息技术的出现及终端计算设备的发展&#xff0c;带来了研发模式、生产模式、消费模式、体制机制的系统性变革&#xff0c;企业应该建设适应工业4.0时代发展要求的新型生产体系。巨蟹数科数字孪生智能工厂通过部署多样化用例…

Java EE 进程线程

JavaEE 进程&线程 文章目录 JavaEE 进程&线程1. 进程1.1 概念1.2 进程管理1.3 PCB (Process Control Block) 2. 线程2.1 概念2.1 线程与进程的区别2.3 创建线程 1. 进程 1.1 概念 什么是进程&#xff1f; 进程是操作系统对一个正在执行的程序的一种抽象 我们可以打开…

Android 相机库CameraView源码解析 (二) : 拍照

1. 前言 这段时间&#xff0c;在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位&#xff0c;在项目前期&#xff0c;的确为我们节省了不少时间。 但随着项目持续深入&#xff0c;对于CameraView的使用进入深水区&#xff0c;逐…

2006-2023年2月地级市城投债数据

2006-2023年2月地级市城投债数据 1、时间&#xff1a;2006-2023年2月 2、指标&#xff1a;省份、城市、证券代码、证券简称、债券简称、证券全称、债券初始面值单位元、债券最新面值交易日期20221231、发行总额单位亿元、债券余额日期20221231单位亿、起息日期、计息截止日、…

2018年10月9日 Go生态洞察:Go Cloud的Wire与编译时依赖注入

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

火柴棒等式

枚举 只要在保证等式正确的基础上判断火柴棒有没有用完就可以 因为数比较小&#xff0c;而且我不知道最大的等式中的数是多少&#xff0c;索性就设置为999了 还好对效率要求不大&#xff08;doge&#xff09; 要不然就得自己慢慢改最大数来试了 代码如下&#xff1a; #in…

树套树 (线段树+splay)

树套树&#xff0c;就是线段树、平衡树、树状数组等数据结构的嵌套。 最简单的是线段树套set&#xff0c;可以解决一些比较简单的问题&#xff0c;而且代码根线段树是一样的只是一些细节不太一样。 本题中用的是线段树套splay&#xff0c;代码较长。 树套树中的splay和单一的…

基于springboot实现农机电招平台系统项目【项目源码+论文说明】

基于springboot实现农机电招平台系统演示 摘要 随着农机电招行业的不断发展&#xff0c;农机电招在现实生活中的使用和普及&#xff0c;农机电招行业成为近年内出现的一个新行业&#xff0c;并且能够成为大群众广为认可和接受的行为和选择。设计农机电招平台的目的就是借助计算…

C++ day37 贪心算法 单调递增的数字 监控二叉树

题目1&#xff1a;738 单调递增的数字 题目链接&#xff1a;单调递增的数字 对题目的理解 返回小于或等于n的最大数字&#xff0c;且数字是单调递增&#xff08;单调递增数字的定义&#xff1a;每个相邻位上的数字满足x<y&#xff09; 贪心算法 注意本题的遍历顺序是从…

写 SVG 动画必看!SVG系列文章1-简介

1、SVG是什么 SVG 是一种 XML 语言&#xff0c;类似 XHTML&#xff0c;可以用来绘制矢量图形&#xff0c;例如下面展示的图形。SVG 可以通过定义必要的线和形状来创建一个图形&#xff0c;也可以修改已有的位图&#xff0c;或者将这两种方式结合起来创建图形。图形和其组成部分…

Vatee万腾科技的未来探险:Vatee数字创新的独特发现

在科技的浩瀚海洋中&#xff0c;Vatee万腾科技如一艘探险船般&#xff0c;勇敢地驶向未知的数字化领域。这次未来的探险&#xff0c;不仅是一场科技创新的冒险&#xff0c;更是对数字化时代的独特发现和深刻探讨。 Vatee万腾科技视科技创新为一座高峰&#xff0c;而他们的未来探…

探究Kafka原理-5.Kafka设计原理和生产者原理解析

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…

SATA信息传输FIS结构总结通过实例代码(快速)掌握(二)

目录 一、简介二、总体介绍2.1 详细FIS传输过程2.2 FIS内容详解 三、FIS实例3.1 构造一个write FIS3.1.1 WRITE FIS内容3.1.2 协议分析仪trace分析3.1.3 write过程总trace 3.2 构造一个read FIS3.2.1 READ FIS内容3.2.2 协议分析仪 read trace3.2.3 read过程总trace 3.3 FIS和C…

【自制】我与GPT3.5合作,一天制作一个生成手写文字图片的软件

视频讲解地址&#xff1a;https://www.bilibili.com/video/BV1uC4y127ME/ bgm我与GPT3.5合作&#xff0c;一天制作一个生成手写文字图片的软件 请给出一个程序&#xff0c;左边显示一个图片&#xff0c;将图片放入进去&#xff0c;可以在里面画出一个框&#xff0c; 右边窗口…

MQTT客户端MQTT.fx 1.7.1下载、安装和界面介绍

MQTT.fx是一款基于Eclipse Paho&#xff0c;使用Java语言编写的MQTT客户端工具。支持通过Topic订阅和发布消息&#xff0c;用来前期和物理云平台调试非常方便。 1.下载 1.1.访问官方下载地址下载&#xff0c;但是下载不到1.7.1版本 1.2.在连接网页末尾点击立即下载&#xff0c;…

Linux(9):正规表示法与文件格式化处理

简单的说&#xff0c;正规表示法就是处理字符串的方法&#xff0c;他是以行为单位来进行字符串的处理行为&#xff0c;正规表示法透过一些特殊符号的辅助&#xff0c;可以让使用者轻易的达到【搜寻/删除/取代】某特定字符串的处理程序。 正规表示法基本上是一种【表示法】&…