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

news/2025/2/22 13:30:37/

二叉树

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

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.ppmy.cn/news/1395944.html

相关文章

Visual Studio项目编译和运行依赖第三方库的项目

1.创建项目&#xff0c;这里创建的项目是依赖于.sln的项目&#xff0c;非CMake项目 2.添加第三方库依赖的头文件和库文件路劲 3.添加第三方依赖库文件 4.项目配置有2个&#xff0c;一个是Debug&#xff0c;一个是Release&#xff0c;如果你只配置了Debug&#xff0c;编译和运行…

15 网络管理与网络安全(2)

1.网络安全服务基本功能 网络安全服务应该提供以下基本保障。 &#xff08;1&#xff09;可用性&#xff1a;可用性是指&#xff0c;尽管存在可能的突发事件&#xff08;例如停电、自然灾害、事故或攻击等&#xff09;情况下&#xff0c;网络仍然可处于正常运转状态&…

Spring IoC DI(1)

IoC & DI入门 Spring 通过前面的学习, 我们知道了Spring是一个开源框架, 它让我们的开发更加简单. 它支持广泛的应用场景, 有着活跃且庞大的社区, 这就是Spring能够长久不衰的原因. 但是这个概念还是比较抽象. 可以用更具体的话描述Spring, 那就是: Spring是包含了众多…

实战|使用 Node.js 和 htmx 构建全栈应用程序

在本教程中&#xff0c;我将演示如何使用 Node 作为后端和 htmx 作为前端来构建功能齐全的 CRUD 应用程序。这将演示 htmx 如何集成到全栈应用程序中&#xff0c;使您能够评估其有效性并确定它是否是您未来项目的不错选择。 htmx 是一个现代 JavaScript 库&#xff0c;旨在通过…

RabbitMQ3.x之二_RabbitMQ所有端口说明及开启后台管理功能

RabbitMQ3.x之二_RabbitMQ所有端口说明及开启后台管理功能 文章目录 RabbitMQ3.x之二_RabbitMQ所有端口说明及开启后台管理功能1. RabbitMQ端口说明2. 开启Rabbitmq后台管理功能1. 查看rabbitmq已安装的插件2. 开启rabbitmq后台管理平台插件3. 开启插件后&#xff0c;再次查看插…

RSTP环路避免实验(华为)

思科设备参考&#xff1a;RSTP环路避免实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 RSTP (Rapid Spanning Tree Protocol) 是从STP发展而来 • RSTP标准版本为IEEE802.1w • RSTP具备STP的所有功能&#xff0c;可以兼容STP运行 • RSTP和STP有所不同 减少了…

第十章:文件

文章目录 第十章&#xff1a;文件10.1-文件概述文件流与缓冲缓冲区 10.2-文件类型指针10.3-文件的打开与关闭文件打开函数fopen()文件关闭函数fclose() 10.4-文件的顺序读写单个字符读写函数fgetc()、fputc() 数据块读写函数&#xff08;二进制方式&#xff09;fread()fwrite()…

【编译tingsboard】出现gradle-maven-plugin:1.0.11:invoke (default)

出现的错误&#xff1a; [ERROR] Failed to execute goal org.thingsboard:gradle-maven-plugin:1.0.11:invoke (default) on project http: Execution default of goal org.thingsboard:gradle-maven-plugin:1.0.11:invoke failed: Plugin org.thingsboard:gradle-maven-plugi…