DAY17||654.最大二叉树 |617.合并二叉树 |700.二叉搜索树中的搜索 |

news2024/11/18 5:33:40

654.最大二叉树

题目:654. 最大二叉树 - 力扣(LeetCode)

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

示例 :

654.最大二叉树

构造二叉树一定要前序遍历,因为要先找到中,才能分割左右子树。

本题图解思路:

 

 

class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        TreeNode*node=new TreeNode(0);
        //如果数组只有一个元素的情况
        if(nums.size()==1){node->val=nums[0];return node;}

        //找到中
        int maxValue=0;
        int maxValueIndex=0;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]>maxValue)
            {
                maxValueIndex=i;
                maxValue=nums[i];
            }
        }
        node->val=maxValue;
        
        //分割左右子树
        //递归构建左子树,新建一个数组
        if(maxValueIndex>0)//保证数组元素大于1,如果不写if的话就要另开一个函数,空的情况返回
        {
            vector<int>leftvec(nums.begin(),nums.begin()+maxValueIndex);//左开右闭写法
            node->left=constructMaximumBinaryTree(leftvec);
        }
        //递归构建右子树
        if(maxValueIndex<nums.size()-1)
        {
            vector<int>rightvec(nums.begin()+maxValueIndex+1,nums.end());
            node->right=constructMaximumBinaryTree(rightvec);
        }
        return node;

    }
};

本题做过上一题构建数组确实变得容易很多。代码优化方向有,不用每次找左右子树的时候构建新的数组的话效率就会高很多。(即直接用下标索引直接在原数组上操作)

关于加不加if的问题,如果允许空节点进入递归,就不加。

617.合并二叉树

题目:617. 合并二叉树 - 力扣(LeetCode)

 

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

617.合并二叉树

注意: 合并必须从两个树的根节点开始

哪种遍历方式都可以。其实就是同时遍历两颗二叉树,相同位置上的元素合并,如果一方有一方没有的情况,就把2的节点加到1中去就可以了。

前序遍历例子:

前中后序的区别只是左中右的顺序调换而已。

前序遍历(递归) 

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1==NULL)return root2;//如果t1为空,返回t2的值。如果两个都为空,那么其实返回的就是NULL了
        if(root2==NULL)return root1;

        root1->val+=root2->val;//合并
        root1->left=mergeTrees(root1->left,root2->left);
        root1->right=mergeTrees(root1->right,root2->right);
        return root1;

    }
};

迭代法(层序遍历) 

使用队列来其实这个写法最好理解思路。

同时遍历,入队列。

需要注意的是节点的左右子树入列的时候,当左子树不为空,右子树为空的情况其实已经被左子树的值加上右子树的值 处理过了

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1==NULL)return root2;
        if(root2==NULL)return root1;

        queue<TreeNode*>que;//一定都不为空入列
        que.push(root1);
        que.push(root2);

        while(!que.empty())
        {
            TreeNode*node1=que.front();que.pop();
            TreeNode*node2=que.front();que.pop();

            node1->val+=node2->val;//合并步骤

            if(node1->left&&node2->left)//两棵树的左子树都在,入列
            {
                que.push(node1->left);
                que.push(node2->left);
            }

            if(node1->right&&node2->right)//两棵树的右子树都在,入列
            {
                que.push(node1->right);
                que.push(node2->right);

            }

            if(!node1->left&&node2->left)//如果1的左空,2的不空,就把2的赋值过去
            {
                node1->left=node2->left;
            }
             if(!node1->right&&node2->right)//如果1的左空,2的不空,就把2的赋值过去
            {
                node1->right=node2->right;
            }
        }
        return root1;//这里返回的是root1而不是node1的原因是,node1只是一个指针,它操作的对象是入了队列的root数
    }
};

其实,定义的node1和node2是一个指针,它指向指针root1和root2.

700.二叉搜索树中的搜索

题目700. 二叉搜索树中的搜索 - 力扣(LeetCode) 

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

例如,

700.二叉搜索树中的搜索

在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL。

 

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。

如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。

递归法

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root==NULL||root->val==val)return root;//如果为空或者找到了值,就返回
        
        //找左子树
        if(root->val>val)return searchBST(root->left,val);

        //找右子树
        if(root->val<val)return searchBST(root->right,val);

        return NULL;

    }
};

迭代法

对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。

对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        while(root)
        {
            if(root->val>val)root=root->left;
            else if(root->val<val)root=root->right;
            else return root;
        }
        return NULL;

    }
};

 本题真的非常简单。因为二叉搜索树的有序性,所以不需要回溯写法。

98.验证二叉搜索树

题目:98. 验证二叉搜索树 - 力扣(LeetCode)

本题看似简单,陷阱挺多的。

我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点

递归法

1.可以中序遍历,把所有节点元素放入一个数组,然后在逐个比较数组是否是递增的。(个人觉得好理解)

class Solution {
    private:
    vector<int>vec;
    void traversal(TreeNode*root)
    {
        if(root==NULL)return;
        if(root->left)traversal(root->left);
        vec.push_back(root->val);
        if(root->right)traversal(root->right);
    }
public:
    bool isValidBST(TreeNode* root) {
        vec.clear();
        traversal(root);
        for(int i=1;i<vec.size();i++)
        {
            if(vec[i]<=vec[i-1])return false;
        }
        return true;

    }
};

2.当然也可以直接在递归遍历时比较节点大小

只有寻找某一条边(或者一个节点)的时候,递归函数会有bool类型的返回值。

其实本题是同样的道理,我们在寻找一个不符合条件的节点,如果没有找到这个节点就遍历了整个树,如果找到不符合的节点了,立刻返回。

class Solution {
public:
    long long maxVal = LONG_MIN; // 因为后台测试数据中有int最小值
    bool isValidBST(TreeNode* root) {
        if(root==NULL)return true;//空二叉树(即没有任何节点的二叉树)被认为是一个有效的二叉搜索树(BST)。
        bool right=isValidBST(root->left);//左
        //中。遍历整棵树,其实如果遇到不是递增的情况就返回false了。
        if(maxVal<root->val)maxVal=root->val;
        else return false;
        bool left=isValidBST(root->right);//右,不需要加if条件判断节点是否为空,因为空节点直接返回true
        return left&&right;
    }
};

maxVal 是一个用于记录当前遍历到的节点值的变量。初始化为 LONG_MIN 是为了确保无论二叉树的节点值多小,它们最初都比这个值大。这是因为二叉搜索树的性质要求,左子树中的所有节点值都小于根节点值。

最终返回值是左子树(right)和右子树(left)验证结果的 逻辑与&&),只有当左右子树都为 BST 时,整棵树才是 BST。

迭代法 

使用栈模拟中序遍历。其实就是双指针法的。一个指针指向树节点,另一个指针指向NULL。当中序遍历走的过程,两指针同步移动,pre一定指向cur的上一个指向的节点。(好理解)

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*>st;
        TreeNode*cur=root;
        TreeNode*pre=NULL;

        while(cur!=NULL||!st.empty())
        {
            if(cur!=NULL)
            {
                st.push(cur);
                cur=cur->left;//左子树入栈,按栈的存储结构和中序遍历特性,只要左树一直不为空,就入栈,反正出栈顺序就是中序遍历的顺序!
            }
            else//如果当前节点为空但栈不为空,就遍历右子树,并且比较是否符合二叉搜索树特性
            {
                cur=st.top();//中
                st.pop();//出栈

                if(pre!=NULL&&cur->val<=pre->val)return false;//错误情况

                pre=cur;//保存上一个数
                cur=cur->right;//右
            }
        }
    return true;  
    }
};

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

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

相关文章

物联网系统中TFT_LCD屏主流驱动方案详解

01 物联网系统中为什么要使用TFT-LCD驱动芯片 在物联网系统中使用TFT-LCD&#xff08;薄膜晶体管液晶显示器&#xff09;驱动芯片的原因主要可以归纳为以下几点&#xff1a; 专业性与高效性 1、专业图形处理&#xff1a;TFT-LCD驱动芯片内置了专业的图形处理引擎&#xff0…

全功能运营级开源跨境电商平台源码 —— 多语言全球化商城解决方案

实测分享【全功能运营级开源跨境电商平台】&#xff0c;它不仅默认集成了中英文双语系统&#xff0c;更内置了强大的翻译接口&#xff0c;支持自动翻译至全球133种语言&#xff0c;为商家打开通往世界的窗口。 核心特性亮点解析&#xff1a; 多语言自动翻译&#xff1a;该平台…

WEB 编程:富文本编辑器 Quill 配合 Pico.css 样式被影响的问题之还是 iframe

这个系列已经写了 3 篇了。这篇写如何使用 iframe 解决标题里面提到的问题。 前情提要 请看上一篇博文&#xff1a; WEB 编程&#xff1a;富文本编辑器 Quill 配合 Pico.css 样式被影响的问题之Shadow DOM WEB 编程&#xff1a;富文本编辑器 Quill 配合 Pico.css 样式被影响…

常见字符函数和字符串函数(上)

1. 字符分类函数 字符分类函数是一类用于判断字符是否属于特定的字符类别&#xff08;如字母、数字、标点符号等&#xff09;的函数。在C语言中&#xff0c;这些函数通常可以在<ctype.h>头文件中找到&#xff0c;它们对于文本处理和输入验证非常有用。 这些函数通常返回…

Windows系统镜像下载

目前官网还可以下载的系统有Win10和Win11&#xff0c;Win7因为已经停止维护&#xff0c;所以只能到第三方镜像站下载&#xff0c;下面将具体展示下载方法。 Win7 下载地址&#xff1a;MSDN, 我告诉你 - 做一个安静的工具站 在操作系统中找到Windows 7&#xff0c;在右侧选择…

Python | Leetcode Python题解之第445题两数相加II

题目&#xff1a; 题解&#xff1a; class Solution:def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:if head is None or head.next is None:return headnew_head self.reverseList(head.next)head.next.next head # 把下一个节点指向自己head…

魔都千丝冥缘——软件终端架构思维———未来之窗行业应用跨平台架构

一、创生-魔都千丝冥缘 在那神秘而复杂的数字世界里&#xff0c;软件的舞台上正上演着一场精彩的剧目。当面对终端单页面中如蛛网般交织的复杂业务逻辑&#xff0c;我们如同在迷雾中摸索前行。多个表单承载着各自的使命&#xff0c;却又有着相同字段的微妙关联&#xff0c;而内…

【C++前缀和 动态规划 贪心】813. 最大平均值和的分组|1936

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C动态规划 贪心(决策包容性) LeetCode813. 最大平均值和的分组 给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个非空子数组&#xff0c;且数组内…

【电商搜索】现代工业级电商搜索技术-Facebook语义搜索技术QueSearch

【电商搜索】现代工业级电商搜索技术-Facebook语义搜索技术Que2Search 目录 文章目录 【电商搜索】现代工业级电商搜索技术-Facebook语义搜索技术Que2Search目录0. 论文信息1. 研究背景&#xff1a;2. 技术背景和发展历史&#xff1a;3. 算法建模3.1 模型架构3.1.1 双塔与分类 …

物流货运托运发货单二联三联打印软件定制 佳易王物流单管理系统操作教程

一、前言 物流货运托运发货单二联三联打印软件定制 佳易王物流单管理系统操作教程 1、软件为绿色免安装版&#xff0c;解压即可使用&#xff0c;已经内置数据库&#xff0c;不需再安装。 2、软件下载可以到本文章最后点击官网卡片下。 二、软件程序教程 1、如图&#xff0c;…

C++入门(2)--引用

6.引用 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 类型& 引用变量名(对象名) 引用实体&#xff1b; //引用 //类型& 引用变量名(对象名) 引…

基于php的幸运舞蹈课程工作室管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

24-9-28-读书笔记(二十)-《契诃夫文集》(四)上([俄] 契诃夫 [译] 汝龙 )

文章目录 《契诃夫文集》&#xff08;四&#xff09;上&#xff08;[俄] 契诃夫 [译] 汝龙 &#xff09;目录阅读笔记记录总结 《契诃夫文集》&#xff08;四&#xff09;上&#xff08;[俄] 契诃夫 [译] 汝龙 &#xff09; 时间过得好快啊&#xff0c;马上又要十月份了&#x…

开源链动2+1模式AI智能名片小程序源码:放大特色,构建独特竞争力

摘要&#xff1a;本文探讨在当今社会背景下&#xff0c;开源链动21模式AI智能名片小程序源码如何通过坚持与众不同来构建独特竞争力。在信息传播便捷但个体易同质化的时代&#xff0c;拥有特色是脱颖而出的关键&#xff0c;而这种模式下的小程序源码具有独特的发展潜力。 一、引…

Golang | Leetcode Golang题解之第443题压缩字符串

题目&#xff1a; 题解&#xff1a; func compress(chars []byte) int {write, left : 0, 0for read, ch : range chars {if read len(chars)-1 || ch ! chars[read1] {chars[write] chwritenum : read - left 1if num > 1 {anchor : writefor ; num > 0; num / 10 {…

bidict:Python 中高效的双向字典库

在 Python 编程中&#xff0c;字典&#xff08;dict&#xff09;是用于存储键值对的强大数据结构&#xff0c;能够快速地根据键查找值。然而&#xff0c;有时我们不仅需要从键查找值&#xff0c;还需要根据值查找键。这种双向查询需求在很多场景中很常见&#xff0c;如映射表、…

openEuler 修改网卡和常用网络配置

简介 1、网卡启用、禁用和查看状态 2、编辑网卡&#xff0c;配置静态Ip 3、删除之前网卡缓存的Ip 4、机器即连接内网&#xff0c;又连接外网 的网卡配置 5、openEuler 修改默认的镜像仓库&#xff08;推荐&#xff09;1、网卡启用、禁用和查看状态 # 查看网络状态 nmcli devi…

muduo网络库介绍

文章目录 MuduoServer常见接口TcpServer类EventLoop类TcpConnection类 服务器搭建Client常见接口TcpClient类 客户端搭建 Muduo Muduo是陈硕大佬开发的,一个基于非阻塞IO和事件驱动的C高并发网络编程库 这是一个基于主从Reactor模型的网络编程库,线程模型是one loop per thre…

K-means聚类分析对比

K-means聚类分析&#xff0c;不同K值聚类对比&#xff0c;该内容是关于K-means聚类分析的&#xff0c;主要探讨了不同K值对聚类结果的影响。K-means聚类是一种常见的数据分析方法&#xff0c;用于将数据集划分为K个不同的类别。在这个过程中&#xff0c;选择合适的K值是非常关键…

VSCode 中配置 C/C++ 环境的步骤

VSCode 中配置 C/C 环境的步骤 1. 安装 VSCode 1、下载位置 https://code.visualstudio.com/Download2、安装 正常操作步骤&#xff0c;同意协议&#xff0c;下一步&#xff0c;点击完成即可 2. 安装 C/C 扩展 打开 VSCode。 点击左侧的扩展图标&#xff08;或使用快捷键…