【数据结构刷题专题】—— 二叉树

二叉树

二叉树刷题框架
在这里插入图片描述
二叉树的定义:

struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(NULL), right(NULL);
};

1 二叉树的遍历方式

【1】前序遍历

class Solution {
public:void traversal(TreeNode* node, vector<int>& vec) {if (node == NULL) return;vec.push_back(node->val);traversal(node->left, vec);traversal(node->right, vec);}vector<int> preorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);return result;}
};

【2】后序遍历

class Solution {
public:void traversal(TreeNode* node, vector<int>& vec) {if (node == NULL) return;traversal(node->left, vec);traversal(node->right, vec);vec.push_back(node->val);}vector<int> postorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);return result;}
};

【3】中序遍历

class Solution {
public:void traversal(TreeNode* node, vector<int>& vec) {if (node == NULL) return;traversal(node->left, vec);vec.push_back(node->val);traversal(node->right, vec);}vector<int> inorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);return result;}
};

【4】层序遍历

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;queue<TreeNode*> que;if (root != NULL) que.push(root);while (!que.empty()) {vector<int> vec;int size = que.size();for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(vec);}return result;}
};

2 二叉树的属性

【1】101. 对称二叉树

class Solution {
public:bool compare(TreeNode* left, TreeNode* right) {if (left != NULL && right == NULL) return false;else if (left == NULL && right != NULL) return false;else if (left == NULL && right == NULL) return true;else if (left->val != right->val) return false;bool outside = compare(left->left, right->right);bool inside = compare(left->right, right->left);return outside && inside;}bool isSymmetric(TreeNode* root) {if (root == NULL) return true;return compare(root->left, root->right);}
};

【2】104. 二叉树的最大深度
迭代法:

class Solution {
public:int maxDepth(TreeNode* root) {if (root == NULL) return 0;int depth = 0;queue<TreeNode*> que;que.push(root);while (!que.empty()) {int size = que.size();depth++;while (size--) {TreeNode* node = que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return depth;}
};

递归法:

class Solution {
public:int getDepth(TreeNode* node) {if (node == NULL) return 0;int left = getDepth(node->left);int right = getDepth(node->right);return 1 + max(left, right);}int maxDepth(TreeNode* root) {return getDepth(root);}
};

【3】111.二叉树的最小深度
递归法:

class Solution {
public:int getDepth(TreeNode* node) {if (node == NULL) return 0;int left = getDepth(node->left);int right = getDepth(node->right);if (node->left != NULL && node->right == NULL) return 1 + left;if (node->left == NULL && node->right != NULL) return 1 + right;return 1 + min(left, right);}int minDepth(TreeNode* root) {return getDepth(root);}
};

迭代法:

class Solution {
public:int minDepth(TreeNode* root) {queue<TreeNode*> que;if (root == NULL) return 0;que.push(root);int depth = 0;while (!que.empty()) {int size = que.size();depth++;while (size--) {TreeNode* node = que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);if (node->left == NULL && node->right == NULL) return depth;}}return depth;}
};

【4】222. 完全二叉树的节点个数
递归法:

class Solution {
public:int getNum(TreeNode* node) {if (node == NULL) return 0;int left = getNum(node->left);int right = getNum(node->right);return 1 + left + right;}int countNodes(TreeNode* root) {return getNum(root);}
};

迭代法:

class Solution {
public:int countNodes(TreeNode* root) {queue<TreeNode*> que;if (root == NULL) return 0;que.push(root);int num = 0;while (!que.empty()) {int size = que.size();while (size--) {TreeNode* node = que.front();que.pop();num++;if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return num;}
};

【5】110. 平衡二叉树

class Solution {
public:int getHeight(TreeNode* node) {if (node == NULL) return 0;int left = getHeight(node->left);if (left == -1) return -1;int right = getHeight(node->right);if (right == -1) return -1;return abs(left - right) > 1 ? -1 : 1 + max(left, right);}bool isBalanced(TreeNode* root) {return getHeight(root) == -1 ? false : true;}
};

【6】257. 二叉树的所有路径

class Solution {
public:void traversal(TreeNode* node, string path, vector<string>& result) {path += to_string(node->val);if (node->left == NULL && node->right == NULL) {result.push_back(path);return;}if (node->left) traversal(node->left, path + "->", result);if (node->right) traversal(node->right, path + "->", result);}vector<string> binaryTreePaths(TreeNode* root) {vector<string> result;string path;if (root == NULL) return result;traversal(root, path, result);return result;}
};

【7】404. 左叶子之和

class Solution {
public:int sumOfLeftLeaves(TreeNode* root) {if (root == NULL) return 0;int left = sumOfLeftLeaves(root->left);if (root->left && root->left->left == NULL && root->left->right == NULL) {left = root->left->val;}int right = sumOfLeftLeaves(root->right);return left + right;}
};

【8】513. 找树左下角的值
迭代法:

class Solution {
public:int findBottomLeftValue(TreeNode* root) {queue<TreeNode*> que;que.push(root);int val = 0;while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();if (i == 0) val = node->val;if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return val;}
};

【9】112. 路径总和

class Solution {
public:bool pathSum(TreeNode* node, int count) {if (node->left == NULL && node->right == NULL && count == 0) return true;if (node->left == NULL && node->right == NULL) return false;if (node->left) {count -= node->left->val;if (pathSum(node->left, count)) return true;count += node->left->val;}if (node->right) {count -= node->right->val;if (pathSum(node->right, count)) return true;count += node->right->val;}return false;}bool hasPathSum(TreeNode* root, int targetSum) {if (root == NULL) return false;return pathSum(root, targetSum - root->val);}
};

【10】543. 二叉树的直径

class Solution {
public:int ans;int Depth(TreeNode* node) {if (node == NULL) return 0;int left = Depth(node->left);int right = Depth(node->right);ans = max(ans, 1 + left + right);return 1 + max(left, right);}int diameterOfBinaryTree(TreeNode* root) {ans = 1;Depth(root);return ans - 1;}
};

【11】124. 二叉树中的最大路径和

class Solution {
public:int ans = INT_MIN;int dfs(TreeNode* node) {if (node == NULL) return 0;ans = max(ans, node->val);int lSum = dfs(node->left);int rSum = dfs(node->right);lSum = max(0, lSum); rSum = max(0, rSum);ans = max(ans, node->val + lSum + rSum);return max(node->val + lSum, node->val + rSum);}int maxPathSum(TreeNode* root) {ans = max(ans, dfs(root));return ans;}
};

3 二叉树的修改和构造

【1】226. 翻转二叉树

class Solution {
public:TreeNode* invertTree(TreeNode* root) {if (root == NULL) return root;swap(root->left, root->right);if (root->left) invertTree(root->left);if (root->right) invertTree(root->right);return root;}
};

【2】106. 从中序与后序遍历序列构造二叉树

class Solution {
public:TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) {if (postorder.size() == 0) return NULL;int rootValue = postorder[postorder.size() - 1];TreeNode* root = new TreeNode(rootValue);if (postorder.size() == 1) return root;int qiege;for (qiege = 0; qiege <= inorder.size(); qiege++) {if (inorder[qiege] == root->val) break;}vector<int> leftInorder(inorder.begin(), inorder.begin() + qiege);vector<int> rightInorder(inorder.begin() + qiege + 1, inorder.end());postorder.resize(postorder.size() - 1);vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());root->left = traversal(leftInorder, leftPostorder);root->right = traversal(rightInorder, rightPostorder);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if (inorder.size() == 0 || postorder.size() == 0) return NULL;return traversal(inorder, postorder);}
};

【3】654. 最大二叉树
构造树一般采用的是前序遍历

class Solution {
public:TreeNode* traversal(vector<int>& nums, int left, int right) {if (left >= right) return NULL;int index = left;for (int i = left + 1; i < right; i++) {if (nums[i] > nums[index]) index = i;}TreeNode* root = new TreeNode(nums[index]);root->left = traversal(nums, left, index);root->right = traversal(nums, index + 1, right);return root;}TreeNode* constructMaximumBinaryTree(vector<int>& nums) {return traversal(nums, 0, nums.size());}
};

【4】617. 合并二叉树

class Solution {
public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if (root1 == NULL) return root2;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;}
};

【5】114. 二叉树展开为链表

class Solution {
public:void traversal(TreeNode* node) {if (node == NULL) return;traversal(node->left);traversal(node->right);TreeNode* left = node->left;TreeNode* right = node->right;node->left = NULL;node->right = left;while (node->right) node = node->right;node->right = right;return;}void flatten(TreeNode* root) {traversal(root);return;}
};

4 求二叉树的属性

【1】700. 二叉搜索树中的搜索

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

【2】98. 验证二叉搜索树

class Solution {
public:long long maxVel = LONG_MIN;bool isValidBST(TreeNode* root) {if (root == NULL) return true;bool left = isValidBST(root->left);if (root->val > maxVel) maxVel = root->val;else return false;bool right = isValidBST(root->right);return left && right;}
};

【3】530. 二叉搜索树的最小绝对差
遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值
把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值

class Solution {
public:vector<int> vec;int ans = INT_MAX;void traversal(TreeNode* node) {if (node == NULL) return;traversal(node->left);vec.push_back(node->val);traversal(node->right);}int getMinimumDifference(TreeNode* root) {traversal(root);for (int i = 1; i < vec.size(); i++) {ans = min(ans, vec[i] - vec[i - 1]);}return ans;}
};

在递归中记录前一个节点的指针

class Solution {
public:int result = INT_MAX;TreeNode* pre = NULL;void traversal(TreeNode* node) {if (node == NULL) return;traversal(node->left);if (pre != NULL) result = min(result, node->val - pre->val);pre = node;traversal(node->right);}int getMinimumDifference(TreeNode* root) {traversal(root);return result;}
};

【4】501. 二叉搜索树中的众数

class Solution {
public:void traversal(TreeNode* cur, unordered_map<int, int>& map) {if (cur == NULL) return;map[cur->val]++;traversal(cur->left, map);traversal(cur->right, map);return;}static bool cmp(const pair<int, int>& a, const pair<int, int>& b) {return a.second > b.second;}vector<int> findMode(TreeNode* root) {unordered_map<int, int> map;vector<int> result;if (root == NULL) return result;traversal(root, map);vector<pair<int, int>> vec(map.begin(), map.end());sort(vec.begin(), vec.end(), cmp);result.push_back(vec[0].first);for (int i = 1; i < vec.size(); i++) {if (vec[0].second == vec[i].second) result.push_back(vec[i].first);else break;}return result;}
};

【5】把二叉搜索树转换为累加树

class Solution {
public:int pre = 0;void traversal(TreeNode* node) {if (node == NULL) return;traversal(node->right);node->val += pre;pre = node->val;traversal(node->left);}TreeNode* convertBST(TreeNode* root) {if (root == NULL) return root;traversal(root);return root;}
};

【6】230. 二叉搜索树中第K小的元素

class Solution {
public:int maxVel = INT_MIN;vector<int> vec;void traversal(TreeNode* node) {if (node == NULL) return;traversal(node->left);if (node->val > maxVel) {vec.push_back(node->val);maxVel = node->val;}traversal(node->right);return;}int kthSmallest(TreeNode* root, int k) {traversal(root);return vec[k - 1];}
};

【7】二叉树的右视图

class Solution {
public:vector<int> rightSideView(TreeNode* root) {vector<int> result;queue<TreeNode*> que;if (root == NULL) return result;que.push(root);while (!que.empty()) {int size = que.size();for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();if (i == (size - 1)) result.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return result;}
};

5 二叉树的公共祖先问题

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

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == p || root == q || root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);if (left != NULL && right != NULL) return root;if (left != NULL && right == NULL) return left;else if (left == NULL && right != NULL) return right;else return NULL;}
};

【2】235. 二叉搜索树的最近公共祖先

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

6 二叉搜索树的修改和构造

【1】二叉搜索树的插入操作

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

【2】450. 删除二叉搜索树中的节点

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == NULL) return root;if (root->val == key) {if (root->left == NULL && root->right == NULL) {delete root;return NULL;} else if (root->left == NULL) {auto tmp = root->right;delete root;return tmp;} else if (root->right == NULL) {auto tmp = root->left;delete root;return tmp;} else {TreeNode* cur = root->right;while (cur->left != NULL) {cur = cur->left;}cur->left = root->left;TreeNode* tmp = root;root = root->right;delete tmp;return root;}}if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};

【3】669. 修剪二叉搜索树

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

【4】108. 将有序数组转换为二叉搜索树

class Solution {
public:TreeNode* traversal(vector<int>& nums, int left, int right) {if (left > right) return NULL;int mid = left + (right - left) / 2;TreeNode* root = new TreeNode(nums[mid]);root->left = traversal(nums, left, mid - 1);root->right = traversal(nums, mid + 1, right);return root;}TreeNode* sortedArrayToBST(vector<int>& nums) {return traversal(nums, 0, nums.size() - 1);}
};

二叉树刷题专题到此结束,读者对题目有更好的解答欢迎讨论。

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

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

相关文章

CI/CD 搭建jenkins基础测试环境构建项目(一)

Jenkins是一个开源的持续集成工具&#xff0c;可以帮助开发团队自动化构建、测试和部署他们的软件项目。通过Jenkins&#xff0c;开发团队可以实现快速、高效地交付软件&#xff0c;并及时发现和解决问题&#xff0c;从而提高团队的生产力和软件质量。持续集成/持续交付&#x…

后端常问面经之操作系统

请简要描述线程与进程的关系,区别及优缺点&#xff1f; 本质区别&#xff1a;进程是操作系统资源分配的基本单位&#xff0c;而线程是任务调度和执行的基本单位 在开销方面&#xff1a;每个进程都有独立的代码和数据空间&#xff08;程序上下文&#xff09;&#xff0c;程序之…

详解多模态 AI

2022 年 11 月&#xff0c;OpenAI 推出了 ChatGPT。它只用了几天时间就以其前所未有的能力席卷了世界。生成式人工智能革命已经开始&#xff0c;每个人都在问同一个问题&#xff1a;下一步是什么&#xff1f; 当时&#xff0c;ChatGPT 和许多其他由大型语言模型 &#xff08;L…

Acer宏碁暗影骑士擎AN515-58笔记本电脑工厂模式原厂Win11系统ISO镜像安装包下载

宏基AN515-58原装出厂OEM预装Windows11系统工厂包&#xff0c;恢复出厂时开箱状态一模一样&#xff0c;带恢复还原功能 链接&#xff1a;https://pan.baidu.com/s/1iCVSYtList-hPqbyTyaRqQ?pwdt2gw 提取码&#xff1a;t2gw 宏基原装系统自带所有驱动、NITROSENSE风扇键盘灯…

4.2 循环语句loop,等差数列求和

汇编语言 1. 循环语句loop loop指令的格式是&#xff1a;loop 标号&#xff0c;CPU执行loop指令的时候&#xff0c;要进行两部操作 cx cx - 1;判断cx中的值&#xff0c;不为0则转至标号处执行程序&#xff0c;如果为0则向下执行 循环使用loop来实现&#xff0c;循环次数存…

Typora结合PicGo + Github搭建个人图床

目录 一 、GitHub仓库设置 1、新建仓库 2、创建Token 并复制保存 二、PicGo客户端配置 1、下载 & 安装 2、配置图床 三、Typora配置 一 、GitHub仓库设置 1、新建仓库 点击主页右上角的 号创建 New repository 填写仓库信息 2、创建Token 并复制保存 点击右上角…

Oracle 使用PLSQL 导出 一个表的insert 语句

1. 使用工具 plsql 的方法,如图示 2. 操作界面(按ctrl键鼠标可多选表) 3. 然后就看到了插入语句 原文&#xff1a;https://www.cnblogs.com/jinanxiaolaohu/p/9192766.html

基于直方图相似性的图像分类算法FPGA实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 MATLAB测试结果&#xff1a; FPGA测试结果&#xff1a; 上述仿真图中&#xff0c;红色XX表示图像读取完毕。因此输出XX。当图像输出完成之后&…

Elasticsearch 索引模板、生命周期策略、节点角色

简介 索引模板可以帮助简化创建和二次配置索引的过程&#xff0c;让我们更高效地管理索引的配置和映射。 索引生命周期策略是一项有意义的功能。它通常用于管理索引和分片的热&#xff08;hot&#xff09;、温&#xff08;warm&#xff09;和冷&#xff08;cold&#xff09;数…

科技类媒体邀约资源有哪些?科技公司做活动如何做好宣传?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 科技类媒体邀约资源包括了各类专注于科技报道的平台和渠道&#xff0c;科技公司可以通过多样化的宣传策略来提升活动的影响力。 科技类媒体资源的邀约通常涉及多种不同的平台和形式&…

基于nodejs+vue高校自习室预约系统的设计与实现python-flask-django-php

本系统在设计过程中&#xff0c;很好地发挥了该开发方式的优势&#xff0c;让实现代码有了良好的可读性&#xff0c;而且使代码的更新和维护更加的方便&#xff0c;操作简单&#xff0c;对以后的维护减少了很多麻烦。系统的顺利开发和实现&#xff0c;对于高校自习室预约这一方…

命令模式(请求与具体实现解耦)

目录 前言 UML plantuml 类图 实战代码 模板 Command Invoker Receiver Client 前言 命令模式解耦了命令请求者&#xff08;Invoker&#xff09;和命令执行者&#xff08;receiver&#xff09;&#xff0c;使得 Invoker 不再直接引用 receiver&#xff0c;而是依赖于…

msvcp100.dll是什么东西?电脑msvcp100.dll丢失的六种解决方法

最近&#xff0c;我在电脑上打开一款软件时&#xff0c;遇到了一个问题&#xff1a;找不到msvcp100.dll丢失问题&#xff0c;为了解决这个问题&#xff0c;我进行了深入的学习和研究&#xff0c;并在此分享msvcp100.dll丢失的解决方法。 一&#xff0c;msvcp100.dll是什么&…

Visual Studio QT6 工程引入组件模块,例如:QtXml

QT 工程引入 QtXml QT 版本 6.6.1 Visual Studio 版本 Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.7.5 打开 Visual Studio 项目工程选择 工具栏 - 扩展 - QT VS Tools -Qt Project Settings 勾选 xml 后点击确定 点击应用即可 注意&#xff1a;配置环…

Apache Dolphinscheduler - 执行工作流却没有创建任务实例分析

问题描述 最近碰到一个奇怪的问题&#xff0c;DS 创建工作流成功&#xff0c;但是一旦执行&#xff0c;始终在转&#xff0c;而且没有任何执行的痕迹&#xff0c;后来到数据库一查发现压根没创建任务实例。 我们都知道一个工作流里面可以挂多个任务节点&#xff0c;执行工作流…

Python 全栈体系【四阶】(十九)

第五章 深度学习 一、基本理论 4. 神经网络的改进 4.3 循环神经网络 4.3.1 标准 CNN 模型的不足 假设数据之间是独立的。标准 CNN 假设数据之间是独立的&#xff0c;所以在处理前后依赖、序列问题&#xff08;如语音、文本、视频&#xff09;时就显得力不从心。这一类数据…

iOS - Runtime-isa详解(位域、union(共用体)、位运算)

文章目录 iOS - Runtime-isa详解&#xff08;位域、union&#xff08;共用体&#xff09;、位运算&#xff09;前言1. 位域介绍1.1 思路1.2 示例 - 结构体1.3 示例 - union&#xff08;共用体&#xff09;1.3.1 说明 1.4 结构体 对比 union&#xff08;共用体&#xff09; 2. a…

【前端】代码案例

1.猜数字 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>猜数字</title> </head> <…

idea运行项目没反应【debug和run灰色】

解决方法 File->Settings->Plugins->groovy 将groovy勾选的√去掉&#xff0c;保存再重新启动idea即可。 啊啊啊码

【微服务】认识Dubbo+基本环境搭建

认识Dubbo Dubbo是阿里巴巴公司开源的一个高性能、轻量级的WEB和 RPC框架&#xff0c;可以和Spring框架无缝集成。Dubbo为构建企业级微服务提供了三大核心能力&#xff1a; 服务自动注册和发现、面向接口的 远程方法调用&#xff0c; 智能容错和负载均衡官网&#xff1a;https…