二叉树题目合集(C++)

news2024/11/23 3:55:33

二叉树题目合集

    • 1.二叉树创建字符串(简单)
    • 2.二叉树的分层遍历(中等)
    • 3.二叉树的最近公共祖先(中等)
    • 4.二叉树搜索树转换成排序双向链表(中等)
    • 5.根据树的前序遍历与中序遍历构造二叉树(中等)

1.二叉树创建字符串(简单)

链接:二叉树创建字符串

题目要求:
在这里插入图片描述

PS:题目描述的不是特别清楚,其实就是前序遍历树,然后用括号分别包含左子树和右子树遍历结果

基础思路:
(1)不考虑括号去重的话,其实只要访问完当前节点后递归访问左右子树即可,并且在访问前加左括号,访问完毕后加右括号,当前节点为空时返回即可。代码如下:

class Solution {
public:
    string ret;
    string tree2str(TreeNode* root) {
        dfs(root);
        return ret;
    }

    void dfs(TreeNode* root)
    {
        if(root == nullptr)  return;
        ret += to_string(root->val);
        ret += '(', dfs(root->left), ret += ')';
        ret += '(', dfs(root->right), ret += ')';
    }
};

在这里插入图片描述


(2) 对于括号去重,主要围绕左右子树为空,我们需要分情况讨论:
在这里插入图片描述


代码:

class Solution {
public:
    string ret;
    string tree2str(TreeNode* root) {
        dfs(root);
        return ret;
    }

    void dfs(TreeNode* root)
    {
        if(root == nullptr)  return;
        ret += to_string(root->val);
        if(root->left || root->right)  ret += '(', dfs(root->left), ret += ')';
        if(root->right)  ret += '(', dfs(root->right), ret += ')';
    }
};



2.二叉树的分层遍历(中等)

链接:二叉树的分层遍历

题目要求:
在这里插入图片描述


基础思路:
(1) 二叉树层序遍历的思想其实很简单,就是借助队列,父节点带出子节点,依靠队列先进先出的特点控制访问顺序
在这里插入图片描述

(2) 这个题目的关键点在于如何得知当前层和下一层的节点数,因为我们需要每一层都构建一个数组来存储结果。这里采用的解决方案是用一个next变量记录下一层的节点数,count(count初始为1)记录当前层的节点数,当前层访问完把next赋给count即可。


代码:

class Solution {
public:
    vector<vector<int>> ret;
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(root == nullptr)  return ret;
        queue<TreeNode*> q;
        q.push(root);
        int count = 1;  //每一层的节点数
        while(!q.empty())
        {
            vector<int> tmp;
            int next = 0;  //用一个变量记录下一层的节点
            for(int i = 0; i < count; i++)
            {
                TreeNode* node = q.front();
                q.pop();
                tmp.push_back(node->val);      
                if(node->left)  q.push(node->left), next++;   
                if(node->right)  q.push(node->right), next++;           
            }
            count = next;
            ret.push_back(tmp);
        }
        return ret;
    }
};



3.二叉树的最近公共祖先(中等)

链接:二叉树的最近公共祖先
题目要求:
在这里插入图片描述

  1. 解法一(时间复杂度高):
    基础思路:
    在这里插入图片描述

解法一代码:

//理想是N*logN,对于退化成链表的情况变成O(N ^ N)
class Solution {
public:
    bool isTree(TreeNode* root, TreeNode* x)
    {
        if(root == nullptr)  return false;
        if(root->val == x->val)  return true;
        return isTree(root->left, x) || isTree(root->right, x);
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == p || root == q)  return root;
        bool pInLeft = isTree(root->left, p);
        bool pInRight = !pInLeft;  //不在左树就在右树
        bool qInLeft = isTree(root->left, q);
        bool qInRight = !qInLeft;
        if((pInLeft && qInRight) || (pInRight && qInLeft))  //p,q分别在左右子树
            return root;
        if(pInLeft && qInLeft)  return lowestCommonAncestor(root->left, p, q); //pq都在左树
        else  return lowestCommonAncestor(root->right, p, q);  //pq都在右树
    }
};

  1. 解法二(时间复杂度低):
    基础思路:
    第二种思路也不是很难,将根到p,q节点的路径找出来从后向前找相交的节点即可,这样不好理解,还是看图:
    在这里插入图片描述

解法二代码:

//找路径,转换为链表交点,用栈来存储路径,O(N)
class Solution {
public:
    bool FindPath(TreeNode* root, TreeNode* x, stack<TreeNode*>& path)
    {
        if(root == nullptr)  return false;
        path.push(root); //不管怎么说,先入栈
        if(root == x)  return true;
        if(FindPath(root->left, x, path))  return true;  //递归走左找到了,直接返回
        if(FindPath(root->right, x, path))  return true;  //递归走右找到了,直接返回
        //左右子树都没有,当前这个节点出栈
        path.pop(); 
        return false;
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        stack<TreeNode*> path1;
        stack<TreeNode*> path2;
        FindPath(root, p, path1);
        FindPath(root, q, path2);
        while(path1.size() != path2.size())  //长路径先走
        {
            if(path1.size() > path2.size())  path1.pop();
            else  path2.pop();
        }
        while(path1.top() != path2.top())
        {
            path1.pop(), path2.pop();
        }
        return path1.top();  //随便返回一个即可
    }
};



4.二叉树搜索树转换成排序双向链表(中等)

链接:二叉树搜索树转换成排序双向链表

题目要求:
在这里插入图片描述

基础思路:
(1)因为是搜索树,我们采用类似中序遍历的方式解题。
(2)这个题的关键在于找前置节点,只要找到当前节点的前置就可以进行链接。

具体过程如下:

  1. 两个指针,prev记录前置,cur记录当前,prev初始为空
  2. cur为空,返回。
  3. (1)cur非空,先递归走左;
    (2)左走完后prev就是前置,链接:cur->left = prev,prev->right = cur(这里prev非空)。
    (3)链接完毕后更新前置,prev = cur
    (4)左走完,递归右,链接右子树。
  4. 最后需要确定链表头节点,这个可以
    ①转换前找:树的最左下角的节点
    ②转换后找:从原根部节点一直向左即可。

先一路递归向左走到空
在这里插入图片描述

代码:

class Solution {
public:
	void _Convert_order(TreeNode* cur, TreeNode*& prev)
	{
		if(cur == nullptr)  return;
		_Convert_order(cur->left, prev);
		cur->left = prev;
		if(prev)  prev->right = cur;
		prev = cur;
		_Convert_order(cur->right, prev);
	}
	
    TreeNode* Convert(TreeNode* pRootOfTree) 
	{
        TreeNode* cur = pRootOfTree, *prev = nullptr;
		_Convert_order(cur, prev);
		TreeNode* ret = pRootOfTree;
		while(ret && ret->left)  //(1)有空树的情况(2)先链接好再向左找目标节点即可
		{
			ret = ret->left;
		}
		return ret;
    }
};



5.根据树的前序遍历与中序遍历构造二叉树(中等)

链接:构造二叉树

题目要求:
在这里插入图片描述

基础思路:
(1)前序定根,中序定左右
(2)先构造根,然后找到当前节点在中序数组的位置,把左右子树的节点划分出来。
(3)依据划分出的中序区间递归走左和右,区间不存在说明这个位置为空,返回空。
左右走完后链接起来即可。左右链接好了返回该树的根部节点

处理细节:
(1)怎么找到当前节点在中序数组的位置:
①一种方式是遍历中序区间,这样每一层都需要遍历,时间复杂度高
②一种是用哈希表进行存储,用值映射中序下标,时间复杂度低。
本文选择方式②。

前序遍历的过程走一下这个过程:
在这里插入图片描述


代码:

class Solution {
public:
    unordered_map<int, int> ord;
    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& prei, int inbegin, int inend)
    {
        if(inbegin > inend)  return nullptr;  //区间不存在返回空
        TreeNode* root = new TreeNode(preorder[prei]);
        int rooti = ord[preorder[prei++]];
        //划分出三段区间:[inbegin, rooti - 1] rooti [rooti + 1, inend]
        root->left = _buildTree(preorder, inorder, prei, inbegin, rooti - 1);
        root->right = _buildTree(preorder, inorder, prei, rooti + 1, inend);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i = 0; i < inorder.size(); i++)
        {
            ord[inorder[i]] = i;
        }
        int i = 0;
        return _buildTree(preorder, inorder, i, 0, inorder.size() - 1);
    }
};

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

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

相关文章

木疙瘩文字变形动画

H5-大 第一步 创建文字到新动画图层 第二步&#xff1a;直接在时间末尾插入变形动画帧 文字专属的参数和形状变化一样都是变形动画才可以动起来&#xff01;关键帧动画主要服务元件&#xff01; 第三步&#xff1a;改变文字参数即可&#xff01;

苍穹外卖-day03

苍穹外卖-day03 课程内容 公共字段自动填充新增菜品菜品分页查询删除菜品修改菜品 **功能实现&#xff1a;**菜品管理 菜品管理效果图&#xff1a; 1. 公共字段自动填充 1.1 问题分析 在上一章节我们已经完成了后台系统的员工管理功能和菜品分类功能的开发&#xff0c;在…

Linux C/C++ 实现网络流量分析(性能工具)

网络流量分析的原理基于对数据包的捕获、解析和统计分析&#xff0c;通过对网络流量的细致观察和分析&#xff0c;帮助管理员了解和优化网络的性能、提高网络安全性&#xff0c;并快速排查和解决网络故障和问题。 Linux中的网络流量常见类型 在Linux中&#xff0c;网络流量可以…

数组与链表算法-链表与多项式

目录 数组与链表算法-链表与多项式 多项式链表表示法 C代码 数组与链表算法-链表与多项式 使用链表的最大好处就是减少内存的浪费&#xff0c;并且能增加使用上的弹性。例如数学上常用的多项式表示法&#xff0c;虽然可以使用数组方式来处理&#xff0c;但当数据内容变动时…

AC修炼计划(AtCoder Regular Contest 164)

传送门&#xff1a;AtCoder Regular Contest 164 - AtCoder A.签到题&#xff0c;在此不做赘述 B - Switching Travel 这题本来该是秒的&#xff0c;但是因为没有考虑清楚环的问题而被卡半天&#xff0c;其实我们不难发现&#xff0c;要想使题目存在节点&#xff0c;就得让该节…

【PC电脑windows-学习样例generic_gpio-ESP32的GPIO程序-基础样例学习】

【PC电脑windows-学习样例generic_gpio-ESP32的GPIO程序-基础样例学习】 1、概述2、实验环境3、 物品说明4、自我总结5、本次实验说明6、实验过程&#xff08;1&#xff09;复制目录到桌面&#xff08;2&#xff09;手动敲写&#xff08;3&#xff09;反复改错&#xff08;4&am…

将知识图谱结合到地铁客流预测中:一个分散注意力关系图卷积网络

导读 论文题目《Combining knowledge graph into metro passenger flow prediction: A split-attention relational graph convolutional network 》。该论文于2023年发表于《Expert Systems With Applications》&#xff0c;文章基于知识图谱&#xff0c;提出了一种分割注意力…

【操作系统】考研真题攻克与重点知识点剖析 - 第 1 篇:操作系统概述

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图与王道考研课程&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术…

数组元素逆序交换

数组元素逆序交换 例如&#xff1a; 输入&#xff1a; 1,2,3,4,5 输出&#xff1a; 5,4,3,2,1 代码&#xff1a; #include<stdio.h> #define N 5 int main() {int a[N], i, temp;for (i 0; i < N; i) {scanf("%d", &a[i]);}for (i 0; i < N…

FL Studio 21.2 升级,支持 Stem 分离和可以发布音乐的 FL Cloud

FL Studio 21.2 带有 stem 分离和 FL Cloud&#xff0c;这是一项专为 FL Studio 打造的具有里程碑意义的新服务。其他新功能包括 FL Studio Fruity Edition 的 Audio Clips&#xff08;音频剪辑&#xff09;和一个新的模拟建模合成器 Kepler。 fl studio 21直装版: https://pan…

JavaEE-cookie和session

本部分内容包括 cookie基本概念&#xff0c;sendcookies和getcookies代码&#xff1b; session基本概念&#xff0c;session实现登陆界面&#xff1b; 上述过程中涉及的代码如下&#xff1a; 1 import javax.servlet.ServletException; import javax.servlet.annotation.WebSe…

2318.不同骰子序列的数目

经典的DP题目&#xff0c;求方案数 从序列中最后一个数字往前考虑 当前状态取决于前一个的状态和再前一个的状态所以dp&#xff08;n&#xff0c;last&#xff0c;last1&#xff09;为当前考虑的是第n个并且前一个数字是last 再前一个数字是last1的所有方案数&#xff0c;递归的…

Leetcode—21.合并两个有序链表【简单】

2023每日刷题&#xff08;十三&#xff09; Leetcode—21.合并两个有序链表 直接法实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* mergeTwoLists(struct ListNode* list1, struct…

0033Java程序设计-基于java的NBA球队运营管理系统的的设计与实现论文

文章目录 摘 要目 录系统设计开发环境 摘 要 本NBA球队运营管理系统设计目标是实现NBA球队运营管理的信息化管理&#xff0c;提高管理效率&#xff0c;使得NBA球队运营管理工作规范化、科学化、高效化。 本文研究的NBA球队运营管理系统基于SSM架构&#xff0c;采用JSP技术、J…

python爬虫selenium和ddddocr使用

python爬虫selenium和ddddocr使用 selenium使用 selenium实际上是web自动化测试工具&#xff0c;能够通过代码完全模拟人使用浏览器自动访问目标站点并操作来进行web测试。 通过pythonselenium结合来实现爬虫十分巧妙。 由于是模拟人的点击来操作&#xff0c;所以实际上被反…

一天掌握python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium

大家好&#xff0c;我是python222小锋老师。前段时间卷了一套 Python3零基础7天入门实战 以及1小时掌握Python操作Mysql数据库之pymysql模块技术 近日锋哥又卷了一波课程&#xff0c;python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium&#xff0c;文字版视频版。1…

[java/力扣110]平衡二叉树——优化前后的两种方法

分析 根据平衡二叉树的定义&#xff0c;只需要满足&#xff1a;1、根节点两个子树的高度差不超过1&#xff1b;2、左右子树都为平衡二叉树 代码 public class BalancedBinaryTree {public class TreeNode{int val;TreeNode left;TreeNode right;TreeNode(){}TreeNode(int va…

基于SSM的n省出口基地公共信息服务平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

软考下午第一题 案列分析

期待分值 10&#xff0c;前三问12左右分&#xff0c;最后一题2、3分左右&#xff0c;重点在于拿下前面三题。 小心谨慎&#xff0c;不要大意。 数据流图 外部系统 数据存储 加工&#xff08;&#xff09;process 数据流 第二小题 说明给出存储名称&#xff0c;就使用该名称&…

C# Socket通信从入门到精通(6)——单个同步TCP服务器监听多个客户端C#代码实现

前言: 我们在C# Socket通信从入门到精通(5)——单个同步TCP服务器监听一个客户端C#代码实现这篇文章中讲述了一个服务器如何与一个客户端进行交互,但是有时候我们需要一个服务器与多个客户端进行交互,这时候上一篇文章介绍的方法就不足以实现这个功能,本篇文章就是介绍如…