二叉树高频题(下)

news/2024/9/30 1:38:22

二叉树高频题(下)

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

using namespace std;struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};class Solution {
public:// 前提:节点的值唯一,p、q都在二叉树中TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {// 如果 p 和 q 中有等于 root 的,那么它们的最近公共祖先即为 root(一个节点也可以是它自己的祖先)if (root == nullptr || root == p || root == q) return root;// 递归遍历左子树,只要在左子树中找到了 p 或 q,则先找到谁就返回谁TreeNode *left = lowestCommonAncestor(root->left, p, q);// 递归遍历右子树,只要在右子树中找到了 p 或 q,则先找到谁就返回谁TreeNode *right = lowestCommonAncestor(root->right, p, q);// 当 left 和 right 均不为空时,说明 p、q 节点分别在 root 异侧, 最近公共祖先即为 rootif (left != nullptr && right != nullptr) return root;// 如果在一侧的子树中 p 和 q 都找不到,则 p 和 q 一定都在另一侧的子树中,另一侧中先遍历到的那个就是最近公共祖先return left == nullptr ? right : left;}
};

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

  • 利用搜索二叉树特性
using namespace std;struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};class Solution {
public:TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {if (root == nullptr || root == p || root == q) return root;// 都比当前根节点的值小,说明都在左子树if (root->val > p->val && root->val > q->val)return lowestCommonAncestor(root->left, p, q);// 都比当前根节点的值大,说明都在右子树if (root->val < p->val && root->val < q->val)return lowestCommonAncestor(root->right, p, q);// 在两侧,当前的根节点就是最近公共祖先return root;}
};
  • 没有利用搜索二叉树特性的做法
class Solution {
public:TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {if (root == nullptr || root == p || root == q) return root;TreeNode *left = lowestCommonAncestor(root->left, p, q);TreeNode *right = lowestCommonAncestor(root->right, p, q);if (left == nullptr) return right;if (right == nullptr) return left;return root;}
};

113. 路径总和 II

#include <vector>using namespace std;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:vector<vector<int>> res;vector<int> path;int target;void dfs(TreeNode *root, int sum) {if (root == nullptr) return;sum += root->val;if (root->left == nullptr && root->right == nullptr && sum == target) {path.emplace_back(root->val);res.emplace_back(vector<int>(path));// 回退路径path.erase(end(path));return;}path.emplace_back(root->val);if (root->left != nullptr) dfs(root->left, sum);if (root->right != nullptr) dfs(root->right, sum);// 回退路径path.erase(end(path));}vector<vector<int>> pathSum(TreeNode *root, int targetSum) {target = targetSum;dfs(root, 0);return res;}
};
class Solution {
public:vector<vector<int>> res;vector<int> path;// 记录节点对应的值在 path 中的下标unordered_map<TreeNode *, int> map;int target;void dfs(TreeNode *root, int sum) {if (root == nullptr) return;path.emplace_back(root->val);map.emplace(root, path.size() - 1);sum += root->val;if (root->left == nullptr && root->right == nullptr && sum == target) {res.emplace_back(vector<int>(path));return;}if (root->left != nullptr) {dfs(root->left, sum);// 回退路径path.erase(begin(path) + map[root->left], end(path));}if (root->right != nullptr) {dfs(root->right, sum);// 回退路径path.erase(begin(path) + map[root->right], end(path));}}vector<vector<int>> pathSum(TreeNode *root, int targetSum) {target = targetSum;dfs(root, 0);return res;}
};

110. 平衡二叉树

#include <algorithm>using namespace std;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:bool balance;int depth(struct TreeNode *node) {if (!balance || node == nullptr) return 0;int left = depth(node->left);int right = depth(node->right);// 不平衡if (abs(left - right) > 1) balance = false;return max(left, right) + 1;}bool isBalanced(TreeNode *root) {balance = true;depth(root);return balance;}
};

98. 验证二叉搜索树

using namespace std;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:TreeNode *pre;// 中序遍历检查是否严格递增bool inorder(TreeNode *root) {if (root == nullptr) return true;if (!inorder(root->left)) return false;if (pre != nullptr && pre->val >= root->val) return false;pre = root;return inorder(root->right);}bool isValidBST(TreeNode *root) {pre = nullptr;return inorder(root);}
};
class Solution {
public:// 判断每个节点是否在他应当在的范围内bool dfs(struct TreeNode *root, long long min, long long max) {if (root == nullptr) return true;if (root->val <= min || root->val >= max) return false;return dfs(root->left, min, root->val) && dfs(root->right, root->val, max);}bool isValidBST(TreeNode *root) {return dfs(root, 0x8000000000000000, 0x7fffffffffffffff);}
};

669. 修剪二叉搜索树

using namespace std;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:TreeNode *trimBST(TreeNode *root, int low, int high) {if (root == nullptr) return nullptr;// 根节点超范围,返回用修剪后的子树,顶替根节点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;}
};

337. 打家劫舍 III

  • 暴力递归
using namespace std;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 rob(TreeNode *root) {if (root == nullptr) return 0;int money = root->val;if (root->left != nullptr)money += rob(root->left->left) + rob(root->left->right);if (root->right != nullptr)money += rob(root->right->left) + rob(root->right->right);// 返回偷 root 和不偷 root 的最大值return max(money, rob(root->left) + rob(root->right));}
};
  • 自上而下记忆化搜索
class Solution {
public:// 记录能偷的最大值unordered_map<TreeNode *, int> dp;int robInternal(TreeNode *root) {if (root == nullptr) return 0;// 如果有就返回if (dp.find(root) != dp.end()) return dp[root];int money = root->val;if (root->left != nullptr)money += (robInternal(root->left->left) + robInternal(root->left->right));if (root->right != nullptr)money += (robInternal(root->right->left) + robInternal(root->right->right));int result = max(money, robInternal(root->left) + robInternal(root->right));dp[root] = result;return result;}int rob(TreeNode *root) {return robInternal(root);}
};
class Solution {
public:int rob(TreeNode* root) {// 返回的是不偷和偷当前节点时,能偷的最大值vector<int> result = recursive(root);return max(result[0], result[1]);}vector<int> recursive(TreeNode* root) {if (root == nullptr) return {0, 0};vector<int> res(2);vector<int> left = recursive(root->left);vector<int> right = recursive(root->right);res[0] = max(left[0], left[1]) + max(right[0], right[1]);res[1] = left[0] + right[0] + root->val;return res;}
};

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

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

相关文章

RocketMQ Offset管理

## Offset管理 ### 1. **Offset 的定义** - **Offset** 表示某个消息在消息队列中的位置。通过 `Offset`,可以准确地找到该消息或者从这个位置开始继续消费消息。- **maxOffset** 表示消息队列中的最大偏移量,是最新消息的 `Offset + 1`。- **minOffset** 是当前消息队列中的…

随书光盘下载使用方法

https://zhujiang.tjufe.edu.cn/tsg/2023/0620/c146a23515/page.htm随书光盘下载使用方法发布时间:2023-06-20浏览次数:3053一、网址访问 1.进入访问链接http://discx.yuntu.io,打开联图云光盘页面(需连接校园网)。 2.在搜索栏输入要搜索的图书isbn或书名。 3.在线使用光…

加入极限科技(INFINI Labs),成为搜索运维工程师!

我们是国内搜索型数据库产品厂商第一梯队的杰出代表,随着业务的快速发展,现开放岗位:搜索运维工程师( Elasticsearch/Easysearch ),如果有兴趣,请直接拉到文末,扫描二维码或将简历投递至 hello@infini.ltd。 如果您还不了解 极限科技(INFINI Labs)是谁,在做什么,需…

Vscode配置Python环境 Pytorch模块和sklearn模块的下载

Vscode配置Python环境 && Pytorch和sklearn模块安装教程 1.下载python解释器首先在python官网下一个Python解释器点击如下的就可以下载了2.python解释器安装 安装过程如下:双击exe文件安装安装成功3.下载VscodeVisual Studio 官网4.配置Vscode点击Vscode来到这个界面V…

Winform中实现拖动 Windows 边缘来调整其大小

Winform中实现无边框窗体只需要设置一个属性FormBorderStyle = FormBorderStyle.None;即可,或者在设计器中直接设置。无边框表单的结果是丢失了标题栏和控制框(最小化、最大值和关闭按钮)。如果没有标题栏,则无法拖动和移动窗口。如果没有边框,则无法拖动 Windows 边缘来调…

《Programming from the Ground Up》阅读笔记:p117-p146

《Programming from the Ground Up》学习第8天,p117-p146总结,总计30页。 一、技术总结 1.共享函数用法示例 (1)不使用共享函数 linux.s: # filename:linux.s# system call numbers(按数字大小排列,方便查看) .equ SYS_READ, 0 .equ SYS_WRITE, 1 .equ SYS_OPEN, 2 .equ SY…

《Python 基础篇》六:面向对象

Python 中的面向对象。Author: ACatSmiling Since: 2024-09-27什么是对象 对象:是内存中专门用来存储数据的一块区域。 对象中可以存放各种数据,比如:数字、布尔值、代码。 对象由三部分组成:对象的标识(id) 对象的类型(type) 对象的值(value)面向对象(oop) Python…

9.23课堂作业

我所选择的主题是安全教育。在校园内外,我们经常听到的、看到的一些不安全事故频繁发生。尽管在校园内,也会有无端横祸向我们飞来,血的教训让我们懂得,校园安全与师生密切相关,关系到学生能否健康成长,完成学业。关系到老师能否在个宁静安全的环境中教书育人。校园安全是…