【面试HOT200】二叉树的构建二叉搜索树篇

系列综述:
💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于【CodeTopHot200】进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证,所有代码均优先参考最佳性能。
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!
🌈【C++】秋招&实习面经汇总篇


文章目录

    • 二叉树的构建
      • 基础知识
        • 654. 构建二叉树*
      • 相关题目
        • 105. 从前序与中序遍历序列构造二叉树
        • 106. 从中序与后序遍历序列构造二叉树
    • 二叉搜索树(考察较少,留后处理)
      • 基础知识
      • 相关题目
        • 98. 验证二叉搜索树
        • 530. 二叉搜索树的最小绝对差
        • 236. 二叉树的最近公共祖先
        • 235. 二叉搜索树的最近公共祖先
        • 450. 删除二叉搜索树中的节点
        • 669. 修剪二叉搜索树
        • 108. 将有序数组转换为二叉搜索树
        • 669. 修剪二叉搜索树
    • 参考博客


😊点此到文末惊喜↩︎

二叉树的构建

基础知识

654. 构建二叉树*
  1. 654. 最大二叉树
    • 通过始末位置指示容器范围,避免每次调用的vector创建开销
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {auto self = [&](auto &&self, int left, int right)->TreeNode*{// 递归出口if (left > right) return nullptr;// 如何划分:查找区间中的最大根节点int max_pos = left;for (int i = left+1; i <= right; ++i) {if (nums[i] > nums[max_pos]) max_pos = i;}// 建立根节点,左递归,右递归TreeNode *root = new TreeNode(nums[max_pos]);root->left = self(self, left, max_pos-1);root->right = self(self, max_pos+1, right);// 返回根节点return root;};TreeNode *root = self(self, 0, nums.size()-1);return root;
}

相关题目

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

    在这里插入图片描述
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder){auto self = [&](auto &&self, int pre_left, int pre_right, int in_left, int in_right)->TreeNode*{// 递归出口:只需要前序的左右指针符合即可if (pre_left > pre_right) return nullptr;// 1. 将前序序列的第一个结点作为根节点TreeNode *root = new TreeNode(preorder[pre_left]);// 2. 找到前序序列的第一个结点在后序序列中的位置作为划分 int pivot = in_left; for (; pivot <= in_right; ++pivot){ // key:注意初始化if (inorder[pivot] == preorder[pre_left]) //  key:查找中序的pivotbreak;}// 3. 计算前序数组中的划分位置int pre_pivot = pre_left + pivot - in_left;// 4. 建立二叉树root->left = self(self, pre_left+1, pre_pivot, in_left, pivot-1);root->right = self(self, pre_pivot+1, pre_right, pivot+1, in_right);return root;};return self(self, 0, preorder.size()-1, 0, inorder.size()-1);
}
106. 从中序与后序遍历序列构造二叉树
  1. 106. 从中序与后序遍历序列构造二叉树

    • 通过始末位置指示容器范围,避免每次调用的vector创建开销
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {auto self = [&](auto &&self, int in_left, int in_right, int post_left, int post_right)->TreeNode*{// 递归出口if (post_left > post_right) return nullptr;// 建立根结点TreeNode *root = new TreeNode(postorder[post_right]);// 在中序数组中查找划分位置int pivot = in_left;for (; pivot <= in_right; ++pivot) {if (inorder[pivot] == postorder[post_right])break;}// 建立左右子树int post_pivot = post_right - (in_right - pivot);// key:注意括号root->left = self(self, in_left, pivot-1, post_left, post_pivot-1);root->right = self(self, pivot+1, in_right, post_pivot, post_right-1);return root;};return self(self, 0, inorder.size()-1, 0, postorder.size()-1);
}

二叉搜索树(考察较少,留后处理)

基础知识

相关题目

98. 验证二叉搜索树
  1. 98. 验证二叉搜索树
    • 中序遍历下,输出的二叉搜索树节点的数值是有序序列
    // **********中序遍历,形成一个递增数组**************
    vector<int> vec;
    void inorder(TreeNode *root){if(root == nullptr) return ;inorder(root->left);vec.push_back(root->val);inorder(root->right);
    }
    // 判断是否中序遍历的数组是递增的
    bool isValidBST(TreeNode* root){inorder(root);for(int i = 0; i < vec.size()-1; ++i){if(vec[i] >= vec[i+1])// 二叉搜索树的中序排列是严格递增的return false;}return true;
    }// *********************纯递归**********************
    bool isValid(TreeNode* current,long left,long right){// 单层逻辑if(current==nullptr) return true;else if(current->val<=left||current->val>=right) return false;// 递归return isValid(current->left,left,current->val)&&isValid(current->right,current->val,right);
    }
    bool isValidBST(TreeNode* root) {return isValid(root,LONG_MIN,LONG_MAX);
    }
    

530. 二叉搜索树的最小绝对差
  1. 530. 二叉搜索树的最小绝对差
    • 思路:中序遍历下,输出的二叉搜索树节点的数值是有序序列。顺序判断相邻值的绝对值,保存最小的即可
    • 双指针在树内应用,双指针本质是对于一个序列的遍历。
    int getMinimumDifference(TreeNode* root) {// 初始化条件stack<TreeNode*> st;if(root != nullptr) st.push(root);int res = INT_MAX;TreeNode *prior = new TreeNode(-1000000);while(!st.empty()){TreeNode* cur = st.top();if(cur != nullptr){st.pop();// 中序遍历if(cur->right) st.push(cur->right);st.push(cur);st.push(nullptr);if(cur->left) st.push(cur->left);}else{st.pop();cur = st.top();st.pop();// 节点处理res = min(res, cur->val - prior->val);prior = cur;// 迭代条件}}return res;
    }
    

236. 二叉树的最近公共祖先
  1. 236. 二叉树的最近公共祖先
    • 后序遍历是一个天然的自低向上的回溯过程
    • 状态的向上传递:通过判断左右子树是否出现了p和q,如果出现p或q则通过回溯值上传到父节点
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == NULL)return NULL;// 每次对返回的结点进行if(root == p || root == q) return root;TreeNode* left =  lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);// 结点的处理是:尽量返回结点if(left == NULL)return right;if(right == NULL)return left;      if(left && right) // p和q在两侧return root;return NULL; // 必须有返回值}
    

235. 二叉搜索树的最近公共祖先
  1. 235. 二叉搜索树的最近公共祖先
    • 思路:自上而下搜索,遇到的第一个节点值在p和q之间的值即为最近公共祖先
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {while(root) {if (root->val > p->val && root->val > q->val) {root = root->left;} else if (root->val < p->val && root->val < q->val) {root = root->right;} else return root;}return NULL;
    }
    

450. 删除二叉搜索树中的节点
  1. 450. 删除二叉搜索树中的节点
    • 思路:框架
    TreeNode* deleteNode(TreeNode* root, int key) {// 健壮性检查if(root == nullptr) return nullptr;// 基本初始化TreeNode *cur = root;TreeNode *prior = root;while (cur != nullptr){// 符合条件值的处理if(cur->val == key){if(cur->left == nullptr || cur->right == nullptr){// 两个都空if(cur->left == nullptr && cur->right == nullptr) return nullptr;// 被删除节点只有一个孩子或均为空if(key < prior->val){// cur是左子树prior->left = cur->right;return root;  }else{prior->right n = cur->right;return root; }}else{// 被删除节点有两个孩子TreeNode *curLeft = cur->left;cur = cur->right;while(cur->left != nullptr){cur = cur->left;}cur->left = curLeft;if(key < prior->val){// cur是左子树prior->left = prior->left->right;return root;  }else{prior->right = prior->right->right;return root; }}}prior = cur;// 前迭代// 左右节点处理if(key < cur->val){if(cur->left){cur = cur->left;}else{// 找不到return root;}}else{if(cur->right){cur = cur->right;}else{// 找不到return root;}}}return root;}
    

669. 修剪二叉搜索树
  1. 669. 修剪二叉搜索树
    // 1. 确定递归函数的返回类型及参数,返回类型是递归算法的输出值类型,参数是递归算法的输入
    TreeNode* trimBST(TreeNode* root, int low, int high) {// 2. 递归终止条件if (root == nullptr ) return nullptr;// 3.节点处理:return保留的状态if (root->val < low) {// 保留更大的右半部分TreeNode* right = trimBST(root->right, low, high);return right;}if (root->val > high) {// 保留更小的左半部分TreeNode* left = trimBST(root->left, low, high); return left;}// 4.迭代条件root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子return root;
    }
    

108. 将有序数组转换为二叉搜索树
  1. 108. 将有序数组转换为二叉搜索树
    TreeNode* traversal(vector<int>& nums, int left, int right) {// 递归出口if (left > right) return nullptr;// 运算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) {TreeNode* root = traversal(nums, 0, nums.size() - 1);return root;
    }
    

669. 修剪二叉搜索树
  1. 669. 修剪二叉搜索树
    // 1. 确定递归函数的返回类型及参数,返回类型是递归算法的输出值类型,参数是递归算法的输入
    TreeNode* trimBST(TreeNode* root, int low, int high) {// 2. 递归终止条件if (root == nullptr ) return nullptr;// 3.节点处理:return保留的状态if (root->val < low) {// 保留更大的右半部分TreeNode* right = trimBST(root->right, low, high);return right;}if (root->val > high) {// 保留更小的左半部分TreeNode* left = trimBST(root->left, low, high); return left;}// 4.迭代条件root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子return root;
    }
    

少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。
不如点赞·收藏·关注一波

🚩点此跳转到首行↩︎

参考博客

  1. 「代码随想录」47. 全排列 II:【彻底理解排列中的去重问题】详解
  2. codetop

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

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

相关文章

Leetcode 77 组合

题意理解&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 如&#xff1a;n3,k2,则有&#xff1a;12 13 23 一般&#xff0c;我们使用回溯法来解决组合问题。 组合问题没有顺序要求&#xff0c;所以 12 21 是同一个组合&#xff08;如…

黑苹果配置清单

手里的MacBookPro已经快沦为电子垃圾了&#xff0c;平时用MacOS比较多&#xff0c;Window用的比较少&#xff0c;而苹果电脑的价格不管是MacBookPro还是MacMini丐版的便宜但是面对现在Window动不动就64g内存的情况就显得微不足道了&#xff0c;高配的价格直接把我劝退&#xff…

PostgreSql HOT 技术

摘自唐成的《PostgreSQL修炼之道&#xff1a;从小工到专家&#xff08;第2版&#xff09;》。 一、概述 因为多版本的原因&#xff0c;当 PostgreSQL 中更新一行时&#xff0c;实际上原数据行并不会被删除&#xff0c;只是插入了一个新行。如果表上有索引&#xff0c;而更新的…

Leetcode题库(数据库合集)_ 难度:中等

目录 难度&#xff1a;中等1.股票的资本损益2. 当选者3. 页面推荐4. 2016年的投资5. 买下所有产品的人6. 电影评分6. 确认率7. 按分类统计薪水8. 餐馆营业额的变化增长8. 即时食物配送 ①9. 至少有5名直系下属的经理10. 游戏玩法分析11. 好友申请&#xff1a;谁有最多的好友12.…

Qlik 成为网络犯罪的焦点

研究人员警告说&#xff0c;Cactus 勒索软件组织正在利用 Qlik Sense 数据可视化、探索和监控解决方案中的关键漏洞来获得对企业网络的初始访问权限。 今年八月下旬&#xff0c;Qlik Sense 开发人员 针对影响 Windows 版本平台的两个关键漏洞发布了补丁 。 其中一个漏洞 CVE-…

图数据库知识点9 | 大数据框架与图数据架构异同

开门见山&#xff0c;直奔主题&#xff0c;接续前面的知识点&#xff1a; 【图数据库知识点1|图数据库与关系型数据库的区别&#xff1f;】 【图数据库知识点2 | 图思维方式】 【图数据库知识点3 | 图数据库解决了什么问题&#xff1f;】 【图数据库知识点4 | 图计算与图数…

基于Echarts的大数据可视化模板:智慧交通管理

目录 引言智慧交通管理的重要性ECharts在智慧交通中的作用智慧交通管理系统架构系统总体架构数据收集与处理Echarts与大数据可视化Echarts库以及其在大数据可视化领域的应用优势开发过程和所选设计方案模板如何满足管理的特定需求模板功能与特性深入解析模板提供的各项功能模板…

2023美图创造力大会开幕,美图发布AI视觉大模型4.0

12月5-6日&#xff0c;主题为“未来AI设计”的美图创造力大会&#xff08;Meitu Creativity Conference&#xff0c;简称MCC&#xff09;在厦门举行。 本届大会由美图公司与站酷联合举办&#xff0c;聚焦于设计师生态和AI设计趋势。大会现场发布《2023年度AI设计实践报告》&am…

JSON 语法详解:轻松掌握数据结构(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息

文章目录 摘要1. 查询CPU使用率命令&#xff1a;top -bn1 | grep \"Cpu(s)\" | awk {split($0,arr,\" \");print 100-arr[8]}2. 查询内存命令&#xff08;单位&#xff1a;G&#xff09;&#xff1a;top -bn1 | grep \"KiB Mem\" | awk {split($…

学生档案管理系统设计

摘要 随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。作为计算机应用的一部分,使用计算机对学生档案信息进行管理,具有着手工管理所无法比拟的优点.例如:检索迅速、查找方便、可靠性高、存储量…

CoreDNS实战(四)-编译安装External Plugins

1 External Plugins概述 coredns官方对于插件的分类基本可以分为三种&#xff1a;Plugins、External Plugins和其他。其中Plugins一般都会被默认编译到coredns的预编译版本中&#xff0c;而External Plugins则不会。官方的文档对外部插件的定义有着明确的解释&#xff0c;主要…

使用 javascript 模拟 git diff 命令实现文本文件差异比较

diff.html&#xff1a; <!DOCTYPE html> <html> <head><title>文件比较</title><meta charset"UTF-8"> </head> <body> <h1>文件比较</h1> <form><label for"file1">版本1&…

第十五届蓝桥杯模拟赛B组(第二期)C++

前言&#xff1a; 第一次做蓝桥模拟赛的博客记录&#xff0c;可能有很多不足的地方&#xff0c;现在将第十五届蓝桥杯模拟赛B组&#xff08;第二期&#xff09;的题目与代码与大家进行分享&#xff0c;我是用C做的&#xff0c;有好几道算法题当时自己做的也是一脸懵&#xff0c…

一键抠图1:Python实现人像抠图 (Portrait Matting)

一键抠图1&#xff1a;Python实现人像抠图 (Portrait Matting) 目录 一键抠图1&#xff1a;Python实现人像抠图 (Portrait Matting) 1. 项目介绍 2. 抠图算法 3. Matting数据集 4. MODNet模型 (1) 项目安装 (2) 数据集说明 (3) MODNet模型 5. Demo测试效果 6. 源码下载…

初级数据结构(一)——顺序表

文中代码源文件已上传&#xff1a;数据结构源码 1、顺序表的特点 1.1、数组 现实中数据记录一般都记录在表格中&#xff0c;如进货单、菜单等&#xff0c;它们的最大特点就是有序。表述中可以用第一项、第二项、第 n 项来描述表格中某个数据或者某串数据。在 C 语言中&#…

开启三层交换机DHCP服务

二层交换机上不需要配置任何东西&#xff0c;只需要在pc机上开启dhcp服务&#xff0c;配置好LSW1后就可以自动获取到IP地址。 sys Enter system view, return user view with CtrlZ. [Huawei]sys sw1 [sw1]dhcp enable Info: The operation may take a few seconds. Please wai…

BUU UPLOAD COURSE 1

传一个cmd.php木马文件 访问一下这个图片地址 发现什么都没有&#xff0c;在hackbar里面连接一下我们的木马 然后看到了一些目录 然后直接查看flag就出来了 这里也可以用蚁剑去连接 直接访问地址&#xff0c;拿着地址去连接就行了。

大数据:sql,数据挖掘刷题

大数据&#xff1a;sql 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql要学&…

22款奔驰C260L升级小柏林音响 无损音质效果

奔驰新款C级号称奔驰轿车的小“S”&#xff0c;在配置方面上肯定也不能低的&#xff0c;提了一台低配的车型&#xff0c;通过后期升级加装件配置提升更高档次&#xff0c;打造独一无二的奔驰C级&#xff0c;此次来安排一套小柏林之声音响&#xff0c;效果怎么样&#xff0c;我们…