代码随想录打卡—day21—【二叉树】— 8.21

1 530. 二叉搜索树的最小绝对差

530. 二叉搜索树的最小绝对差

想法:先直接中序遍历(升序的序列)过程中相邻两个数的差值取min,自己写一次AC代码:

/**
 * 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 min_ans;
    int ok = 0;   //全局遍历 第一个元素特殊处理!
    TreeNode* old;   //全局遍历!
    int search(TreeNode* root)  // 返回前一个节点的val
    {
        if(!root) return root->val;
        
        int ans1 = 0xffff;
        int ans2 = 0xffff;

        if(root->left)ans1 = search(root->left);

        int tmpval = root->val;
        cout << tmpval << endl;
        if(ok)min_ans = min(min_ans,abs(tmpval - old->val));
        old = root;
        ok=1;

        if(root->right)ans2 = search(root->right);
        
        return tmpval;
    }

    int getMinimumDifference(TreeNode* root) 
    {
        // 想法:先直接中序遍历(升序的序列)相邻两个数的差值取min
        min_ans = INT_MAX;
        ok=0;
        search(root);
        return min_ans;
    }
};


看了题解,思路和我的一样,但是写法更加简单(设置old起始为null,非null表示非第一次,并且后一步每次都更新old ),学习并写一遍AC代码:

/**
 * 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_MAX;
    TreeNode* old =  NULL;
    void search(TreeNode* root)
    {
        if(root == NULL)return;
        search(root->left);
        if(old)
            ans = min(ans,abs(root->val - old->val));
        old = root;
        search(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        search(root);
        return ans;
    }
};

 2 501. 二叉搜索树中的众数

501. 二叉搜索树中的众数

如果拿一个数组存中序遍历结果很容易,但是题目进阶要求:不要额外的空间。有一些麻烦的思路,比如全局变量维护max的值与数目,每次函数都传递当前值和数目的参数(题解证明不用传参 直接全局变量更新新的cnt即可),不确定能不能实现,然后看题解:

  • 知道了普通二叉树的做法时候:最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序(有的同学可能可以想直接对map中的value排序,还真做不到,C++中如果使用std::map或者std::multimap可以对key排序,但不能对value排序。所以要把map转化数组即vector,再进行排序,当然vector里面放的也是pair<int, int>类型的数据,第一个int为元素,第二个int为出现频率。),最后取前面高频的元素的集合。
  • 在递归遍历二叉搜索树的过程中,介绍了一个统计最高出现频率元素集合的技巧, 要不然就要遍历两次二叉搜索树才能把这个最高出现频率元素的集合求出来。为什么没有这个技巧一定要遍历两次呢? 因为要求的是集合,会有多个众数,如果规定只有一个众数,那么就遍历一次稳稳的了。和我的思路差不多,就是把我模糊的想法落地了。

/**
 * 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 cnt = INT_MIN;
    int maxcnt = INT_MIN;

    TreeNode* old = NULL;
    vector<int> ans;
    void search(TreeNode* root)
    {
        if(root == NULL)return;
        search(root->left);
        // 计算当前cnt
        if(!old)cnt = 1;
        else
        {
            if(root->val == old->val)
                cnt++;
            else  //新的元素
                cnt = 1;
        }
        // 计算最大的cnt 和 更新结果
        if(cnt > maxcnt)
        {
            maxcnt = cnt;
            ans.clear();
            ans.push_back(root->val);
        }
        else if(cnt == maxcnt)ans.push_back(root->val);

        old = root;

        search(root->right);

    }
    vector<int> findMode(TreeNode* root) 
    {
        search(root);
        return ans;
    }
};

3 236. 二叉树的最近公共祖先

236. 二叉树的最近公共祖先

我一开始写了一个递归的版本,其实只用了递归但没有迭代,结果在第29个测试点超出内存限制,不知道是不是TLE,如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<TreeNode*>> ans;
    void search(TreeNode* root, TreeNode* p, TreeNode* q,vector<TreeNode*> path)
    {
        if(root == p || root == q)  // 获得结果并不return
            ans.push_back(path);

        if(!root->left && !root->right)
            return;
        
        path.push_back(root->left);
        if(root->left)search(root->left,p,q,path);
        path.pop_back();

        path.push_back(root->right);
        if(root->right)search(root->right,p,q,path);
        path.pop_back();

    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //我的思路 写一个函数找到p和q的祖宗路线存在来然后对比两个序列即可。
        vector<TreeNode*> path;
        path.push_back(root);
        search(root , p , q ,path);

        int i = 0;
        for(; i < ans[0].size();i++)
            if(ans[0][i] != ans[1][i])
                return ans[0][i-1];

        return ans[0][i-1];
    }
};

看了题解,正确的思路应该是不止递归,更要好好用到回溯==》后序遍历,基本逻辑是:

  • 如果当前节点是p,是q,或者是空直接返回当前节点。(想象如果p是q的父节点 这里的直接return也是满足要求的!!!)
  • 后序遍历后:
  1. 左子树如果没有pq,右子树也没有pq,就return 空
  2. 左子树如果没有pq,右子树有pq,就返回右子树的结果
  3. 左子树如果有pq,右子树没有pq,就返回左子树的结果
  4. 左右都有的话,说明当前节点就是最近的公共父节点!!!!!!!

我感觉这个写法还是比较妙的写法,有一些一个变量表达2个含义的感觉,没有冗余的东西AC代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* search(TreeNode* root, TreeNode* p, TreeNode* q)
    {
        if(root == p || root == q || root == NULL)  // 获得结果并不return
            return root;
        
        TreeNode* left = search(root->left,p,q);
        TreeNode* right = search(root->right,p,q);

        if(left && right)return root;
        else if(left && !right)return left;
        else if(!left && right)return right;
        else return NULL;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {

        return search(root , p , q );
    }
};

总结:

这一节累计用时2h。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于视频监控平台EasyCVR视频汇聚平台建设“明厨亮灶”具体实施方案以及应用

一、方案背景 近几年来&#xff0c;餐饮行业的食品安全、食品卫生等新闻频频发生&#xff0c;比如某火锅店、某网红奶茶&#xff0c;食材以次充好、后厨卫生被爆堪忧&#xff0c;种种问题引起大众关注和热议。这些负面新闻不仅让餐饮门店的品牌口碑暴跌&#xff0c;附带的连锁…

爬虫工具的选择与使用:阐述Python爬虫优劣势

作为专业爬虫ip方案解决服务商&#xff0c;我们每天都面对着大量的数据采集任务需求。在众多的爬虫工具中&#xff0c;Python爬虫凭借其灵活性和功能强大而备受青睐。本文将为大家分享Python爬虫在市场上的优势与劣势&#xff0c;帮助你在爬虫业务中脱颖而出。 一、优势篇 灵活…

32.Netty源码之服务端如何处理客户端新建连接

highlight: arduino-light 服务端如何处理客户端新建连接 Netty 服务端完全启动后&#xff0c;就可以对外工作了。接下来 Netty 服务端是如何处理客户端新建连接的呢&#xff1f; 主要分为四步&#xff1a; md Boss NioEventLoop 线程轮询客户端新连接 OP_ACCEPT 事件&#xff…

分享图片 | 快速浏览网页资源,批量保存、一键分享图片

前言 小伙伴学习吉他&#xff0c;有时需要在互联网搜索曲谱资源&#xff0c;而多数曲谱均为图片&#xff0c;并且为多页&#xff0c;在电脑上显示练习很不方便&#xff0c;需要停下来点击鼠标进行翻页&#xff0c;影响练习的连贯性。 为了解决上述问题&#xff0c;通常把图片…

【数据分析入门】Jupyter Notebook

目录 一、保存/加载二、适用多种编程语言三、编写代码与文本3.1 编辑单元格3.2 插入单元格3.3 运行单元格3.4 查看单元格 四、Widgets五、帮助 Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。 …

宇宙原理:黑洞基础。

宇宙原理&#xff1a;黑洞基础TOC 黑洞的数理基础&#xff1a;一个由满数组成的数盘&#xff0c;经过自然演进&#xff0c;将会逐步稀疏化、最终会向纯数方案发展&#xff1b;纯数方案虽然只有{2}、无数&#xff08;虚拟&#xff09;、{0,1,2,3}&#xff08;虚拟&#xff09;、…

jenkins同一jar包部署到多台服务器

文章目录 安装插件配置ssh服务构建完成后执行 没有部署过可以跟这个下面的步骤先部署一遍&#xff0c;我这篇主要讲jenkins同一jar包部署到多台服务器 【Jenkins】部署Springboot项目https://blog.csdn.net/qq_39017153/article/details/131901613 安装插件 Publish Over SSH 这…

量子非凡去广告接口

量子非凡去广告接口&#xff0c;免费发布&#xff0c;请各位正常调用&#xff0c;别恶意攻击 >>>https://videos.centos.chat/weisuan.php/?url

深入浅出带你玩转栈与队列——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 目录 1.栈 1.1栈的概念及结构 1.2栈的结构特征图 ​编辑 1.3栈的实现 1.3.1栈的初始化 1.3.2进栈 1.3.3出栈 1.3.4销毁内存 1.3.5判断栈是否为空 1.3.5栈底元素的读取 1.3.6栈中大小 1.4栈实现所有接口 2…

Python“牵手”拼多多商品评论数据采集方法,拼多多API申请步骤说明

拼多多平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范&#xff0c;拼多多API接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问拼多多平台的数据&#xff0c;包括商品信息、店铺信息、物流信息&#xff0c;评论数据等&a…

无涯教程-Perl - splice函数

描述 此函数从LENGTH元素的OFFSET元素中删除ARRAY元素,如果指定,则用LIST替换删除的元素。如果省略LENGTH,则从OFFSET开始删除所有内容。 语法 以下是此函数的简单语法- splice ARRAY, OFFSET, LENGTH, LISTsplice ARRAY, OFFSET, LENGTHsplice ARRAY, OFFSET返回值 该函数…

2024浙大MBA/MEM/MPA四个月冲刺备考策略

近期收到很多考生的咨询&#xff1a;距离联考就仅剩四个多月的时间&#xff0c;这个管理类联考的难度如何&#xff1f;主要考些什么内容&#xff1f;现在才开始备考还有希望上岸浙大吗&#xff1f;是不是要等到明年在开始备考比较合适&#xff1f;那么今天在这里小立老师就跟大…

管家婆中了mallox勒索病毒该怎么办?勒索病毒解密数据恢复

管家婆是很多中小企业使用的财务软件&#xff0c;它的性价比高、操作简单&#xff0c;适用行业也非常广。这也是它能够赢得众多中小企业主欢迎的原因之一。俗话说的好&#xff0c;木秀于林风必摧之&#xff0c;正是因为管家婆有着非常庞大的使用群体&#xff0c;所以它才成为了…

Stable Diffusion训练Lora模型

以下内容参考:https://www.bilibili.com/video/BV1Qk4y1E7nv/?spm_id_from333.337.search-card.all.click&vd_source3969f30b089463e19db0cc5e8fe4583a 1、训练Lora的2个重点步骤 第一步&#xff0c;准备训练要使用的图片&#xff0c;即优质的图片 第二部&#xff0c;为…

【vue3】对axios进行封装,方便更改路由并且可以改成局域网ip访问(附代码)

对axios封装是在main.js里面进行封装&#xff0c;因为main.js是一个vue项目的入口 步骤&#xff1a; 在1处创建一个axios实例为http&#xff0c;baseURL是基础地址&#xff08;根据自己的需求写&#xff09;&#xff0c;写了这个在vue界面调用后端接口时只用在post请求处写路由…

【深入解析:数据结构栈的魅力与应用】

本章重点 栈的概念及结构 栈的实现方式 数组实现栈接口 栈面试题目 概念选择题 一、栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数…

Masterstudy主题 - 用于线上教育、在线学习和在线课程的LMS WordPress主题

Masterstudy主题是每个人的最佳选择&#xff01;它是一个完整的线上教育WordPress主题&#xff0c;适合所有想要创建在线课程、辅导和语言中心、在线学习平台并在全球范围内传播知识的人。这是一个完美的教育主题&#xff0c;旨在满足学习行业的需求。 网址&#xff1a;Master…

【数据结构练习】单链表OJ题(一)

目录 一、移除链表元素思路1&#xff1a;思路2&#xff1a; 二、反转链表三、链表的中间节点四、链表中倒数第k个节点五、回文结构六、合并两个有序链表 一、移除链表元素 题目&#xff1a; 思路1&#xff1a; 在原来的链表上进行修改&#xff0c;节点的数据是val的删除&am…

axios 各种方式的请求 示例

GET请求 示例一&#xff1a; 服务端代码 GetMapping("/f11") public String f11(Integer pageNum, Integer pageSize) {return pageNum " : " pageSize; }前端代码 <template><div class"home"><button click"getFun1…

时序预测 | MATLAB实现ELM极限学习机时间序列预测(多指标、相关图)

时序预测 | MATLAB实现ELM极限学习机时间序列预测(多指标、相关图) 目录 时序预测 | MATLAB实现ELM极限学习机时间序列预测(多指标、相关图)效果一览基本介绍程序设计学习总结参考资料效果一览 基本介绍 时序预测 | MATLAB实现ELM极
最新文章