当前位置: 首页 > news >正文

leetcode hot100 二叉树(二)

书接上回:https://blog.csdn.net/weixin_74129837/article/details/148367615?spm=1001.2014.3001.5501

8.验证二叉搜索树

维护一个min_val和max_val,限制当前结点的合法值范围。min_val和max_val动态变化。

class Solution {
public:bool check(TreeNode* node,long min_val,long max_val){if(!node) return true;if(node->val<=min_val||node->val>=max_val) return false;  //注意定义,等于也不行return check(node->left,min_val,node->val)&&check(node->right,node->val,max_val);}bool isValidBST(TreeNode* root) {return check(root,LONG_MIN,LONG_MAX);}
};

9.二叉搜索树中第k小的元素

在BST中,中序遍历(左-根-右)会按升序访问所有节点

因此,第k个被访问的节点就是第k小的元素。

代码本质上是迭代实现的中序遍历,并通过提前终止(剪枝)来优化。

算法流程:向左深入->回溯到父结点->转向右子树。

class Solution {
public:int kthSmallest(TreeNode* root, int k) {stack<TreeNode*> stk;while(root||stk.size()){while(root){stk.push(root);  root=root->left;} root=stk.top();  //取出最后遍历到的父结点(相当于回溯)stk.pop();if(--k==0) return root->val;root=root->right;}return root->val;}
};

10.二叉树的右视图

dfs遍历,且优先遍历右子树。

如果层数==res大小,说明当前层还未加入结点,即本次递归到的结点是当前层右数第一个结点。

class Solution {
public:void dfs(TreeNode* root,vector<int>& res,int u){if(!root) return ;//在搜索过程中总是先访问右子树//对于每一层来说,这层见到的第一个结点一定是最右边的结点//u==res.size()时,当前层级u还没有被记录到res中(res 的索引是0到u-1,共u层)if(u==res.size()) res.push_back(root->val);dfs(root->right,res,u+1);dfs(root->left,res,u+1); }vector<int> rightSideView(TreeNode* root) {vector<int> res;if(!root) return res;dfs(root,res,0);return res;}
};

 11.二叉树展开为链表

核心:展开的单链表与二叉树先序遍历的顺序相同。

class Solution {
public:void flatten(TreeNode* root) {vector<TreeNode*> nodes; // 用于存储先序遍历的结果preorderTraversal(root,nodes); // 获取先序遍历结果int n=nodes.size();for (int i=1;i<n;i++){TreeNode* prev=nodes[i-1];TreeNode* curr=nodes[i];prev->left=nullptr; // 左子指针置空prev->right=curr;   // 右子指针指向下个节点}}//先序遍历:根->左->右void preorderTraversal(TreeNode* root,vector<TreeNode*> &l){if(root){l.push_back(root);preorderTraversal(root->left,l);preorderTraversal(root->right,l);}}
};

12.从前序与中序遍历序列构造二叉树

class Solution {
private:unordered_map<int,int> index;
public:TreeNode* build(vector<int>& pre,vector<int>& in,int pre_left,int pre_right,int in_left,int in_right){if(pre_left>pre_right) return nullptr;int pre_root=pre_left;  //pre_root是索引int in_root=index[pre[pre_root]];int left_size=in_root-in_left;TreeNode* root=new TreeNode(pre[pre_root]);root->left=build(pre,in,pre_left+1,pre_left+left_size,in_left,in_root-1);root->right=build(pre,in,pre_left+left_size+1,pre_right,in_root+1,in_right);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int n=preorder.size();for(int i=0;i<n;i++) index[inorder[i]]=i;return build(preorder,inorder,0,n-1,0,n-1);}
};

13.路径总和

        如图,先利用先序遍历序列确定根节点,再利用中序遍历序列递归子树,关键是递归边界的确定。

class Solution {
public:int dfs(TreeNode* node,long sum,int target){if(!node) return 0;int cnt=0;if(sum+node->val==target) cnt++;cnt+=dfs(node->left,sum+node->val,target);cnt+=dfs(node->right,sum+node->val,target);return cnt;} int pathSum(TreeNode* root, int targetSum) {if(!root) return 0;int cnt=dfs(root,0,targetSum);cnt+=pathSum(root->left,targetSum);cnt+=pathSum(root->right,targetSum);return cnt;}
};

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

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(!root) return nullptr;if(p==root||q==root) return root;TreeNode* left=lowestCommonAncestor(root->left,p,q);TreeNode* right=lowestCommonAncestor(root->right,p,q);if(right&&left) return root;  //左右节点都有,最近公共祖先是根结点if(left) return left;  //只有左结点if(right) return right;  //只有右结点return nullptr;}
};

15.二叉树的最大路径和

  • 后序遍历:采用DFS的后序遍历方式(左右根)来遍历整棵树。
  • 计算单边最大增益:对于每个节点,计算其左子树和右子树能提供的最大增益(如果增益为负则取0,表示不选择该子树)。
  • 更新全局最大值:对于当前节点,计算包含该节点及其左右子树的最大路径和(即node->val + left_gain + right_gain),并更新全局最大值max_sum
  • 返回单边最大路径:向上返回时只能选择左或右子树中增益较大的一边加上当前节点的值。
class Solution {
public:int dfs(TreeNode* node,int& max_sum){if(!node) return 0;int left_gain=max(dfs(node->left,max_sum),0);int right_gain=max(dfs(node->right,max_sum),0);int curr_sum=node->val+left_gain+right_gain;max_sum=max(max_sum,curr_sum);return node->val+max(left_gain,right_gain);}int maxPathSum(TreeNode* root) {int max_sum=INT_MIN;dfs(root,max_sum);return max_sum;}
};

相关文章:

  • 【黑马程序员uniapp】项目配置、请求函数封装
  • 如何使用DAXStudio将PowerBI与Excel连接
  • 天机学堂-分页查询
  • 从线性方程组角度理解公式 s=n−r(3E−A)
  • 【头歌实验】Keras机器翻译实战
  • C++.双指针算法(1.1目录修正)
  • nssctf第二题[SWPUCTF 2021 新生赛]简简单单的逻辑
  • Redis-6.2.9 cluster集群部署和扩容缩容
  • DeepSeek模型性能优化:从推理加速到资源调度的全栈实践
  • 【笔记】部署 AgenticSeek 项目问题:端口 8000 被占用
  • 结构型设计模式之桥接模式
  • 【设计模式-3.6】结构型——桥接模式
  • 【Qt开发】对话框
  • 3516cv610在sample_aiisp上多创一路编码流,方法
  • 设计模式——中介者设计模式(行为型)
  • Git GitHub Gitee
  • github 2FA双重认证丢失解决
  • SQL Transactions(事务)、隔离机制
  • 【C语言预处理详解(下)】--#和##运算符,命名约定,命令行定义 ,#undef,条件编译,头文件的包含,嵌套文件包含,其他预处理指令
  • PyTorch——卷积操作(2)
  • wordpress 信息分析/怎么关闭seo综合查询
  • 代理商加盟网站/想要推广网页
  • 京东不让卖网站制作么/上海网络营销seo
  • wordpress 4.7.2 提权/seo专业培训seo专业培训
  • 合肥做网站联系方式/长春seo优化
  • 哪些网站可以做简历/互联网站