LeetCode700. 二叉搜索树中的搜索

700. 二叉搜索树中的搜索

文章目录

      • [700. 二叉搜索树中的搜索](https://leetcode.cn/problems/search-in-a-binary-search-tree/)
        • 一、题目
        • 二、题解
          • 方法一:迭代
          • 方法二:递归
        • 带main函数测试用例


一、题目

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null

示例 1:

img

输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

示例 2:

img

输入:root = [4,2,7,1,3], val = 5
输出:[]

提示:

  • 数中节点数在 [1, 5000] 范围内
  • 1 <= Node.val <= 107
  • root 是二叉搜索树
  • 1 <= val <= 107

二、题解

方法一:迭代

首先要理解题目的要求:给定一个二叉搜索树(BST)和一个整数值,要求在这个BST中找到值等于给定整数的节点,并返回以该节点为根的子树。如果节点不存在,则返回 null。为了解决这个问题,我们可以分为以下几个步骤:

算法思路:

  1. 首先,我们需要明确二叉搜索树的性质:对于任意节点,其左子树的所有节点值都小于它,右子树的所有节点值都大于它。这个性质使得我们可以在搜索过程中有效地缩小搜索范围。

  2. 我们从根节点开始,进行迭代搜索。首先,我们初始化一个指针 node 指向根节点。

  3. 在迭代过程中,我们不断比较当前节点的值与给定值 val 的大小关系:

    • 如果当前节点的值等于 val,那么就找到了目标节点,直接返回该节点。
    • 如果当前节点的值小于 val,说明目标节点可能在当前节点的右子树中,因此更新 node 为当前节点的右子节点。
    • 如果当前节点的值大于 val,说明目标节点可能在当前节点的左子树中,因此更新 node 为当前节点的左子节点。
  4. 重复步骤 3,直到找到目标节点或者搜索范围为空(即 node 为空),此时返回 null 表示没有找到目标节点。

具体实现:

class Solution {
public:TreeNode* searchBST(TreeNode* root, int val) {if(root == nullptr) return nullptr; // 如果根节点为空,直接返回 nullptrTreeNode *node = root; // 初始化指针 node 指向根节点while(node != nullptr){if(node->val == val){ // 当前节点的值等于目标值,直接返回该节点return node;}else if(node->val < val){ // 当前节点的值小于目标值,更新 node 为右子节点node = node->right;}else{ // 当前节点的值大于目标值,更新 node 为左子节点node = node->left;}}return node; // 返回找到的节点,或者返回 nullptr(没有找到)}
};

算法分析:

  • 时间复杂度:在最坏情况下,我们需要遍历整棵树,时间复杂度为 O(n),其中 n 是树中节点的个数。但由于是二叉搜索树,平均情况下,搜索范围会逐步缩小,期望时间复杂度更接近 O(log n)。
  • 空间复杂度:由于只使用了常数级别的额外空间来存储指针,空间复杂度为 O(1)。
方法二:递归

算法思路:

  1. 首先,我们对根节点进行判空,如果根节点为空,直接返回 nullptr,表示没有找到目标节点。

  2. 然后,我们判断当前根节点的值与目标值 val 的关系:

    • 如果当前根节点的值等于 val,说明已经找到目标节点,直接返回该根节点。
    • 如果当前根节点的值小于 val,说明目标节点可能在右子树中,因此递归调用 searchBST(root->right, val),在右子树中继续搜索。
    • 如果当前根节点的值大于 val,说明目标节点可能在左子树中,因此递归调用 searchBST(root->left, val),在左子树中继续搜索。
  3. 递归继续执行上述步骤,直到找到目标节点或者遍历到叶子节点为止。如果遍历到叶子节点仍然没有找到目标节点,则返回 nullptr

具体实现:

class Solution {
public:TreeNode* searchBST(TreeNode* root, int val) {if (root == nullptr) return nullptr; // 如果根节点为空,直接返回 nullptrif (root->val == val) return root; // 当前根节点的值等于目标值,返回该根节点if (root->val < val) {return searchBST(root->right, val); // 在右子树中继续搜索} else {return searchBST(root->left, val); // 在左子树中继续搜索}}
};

算法分析:

  • 时间复杂度:在最坏情况下,我们需要遍历整棵树,时间复杂度为 O(n),其中 n 是树中节点的个数。但由于是二叉搜索树,平均情况下,搜索范围会逐步缩小,期望时间复杂度更接近 O(log n)。
  • 空间复杂度:由于使用递归调用,系统需要维护递归调用栈,空间复杂度取决于递归深度。在平均情况下,空间复杂度为 O(log n),在最坏情况下,即树高为 n 时,空间复杂度为 O(n)。

带main函数测试用例

#include <iostream>
#include <vector>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* searchBST(TreeNode* root, int val) {if (!root) return nullptr; // 根节点为空,直接返回 nullptrif (root->val == val) return root; // 当前根节点的值等于目标值,返回该根节点return root->val < val ? searchBST(root->right, val) : searchBST(root->left, val);}
};int main() {// 构建测试用例TreeNode* root = new TreeNode(4);root->left = new TreeNode(2);root->right = new TreeNode(7);root->left->left = new TreeNode(1);root->left->right = new TreeNode(3);int target = 2;Solution solution;TreeNode* result = solution.searchBST(root, target);std::vector<int> output;// 遍历得到的子树节点,将值存入输出向量中std::vector<TreeNode*> stack;TreeNode* current = result;while (current || !stack.empty()) {while (current) {stack.push_back(current);current = current->left;}current = stack.back();stack.pop_back();output.push_back(current->val);current = current->right;}// 输出结果for (int val : output) {std::cout << val << " ";}std::cout << std::endl;// 释放内存(实际情况中可能需要编写更详细的内存释放逻辑)delete root->left->right;delete root->left->left;delete root->left;delete root->right;delete root;return 0;
}

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

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

相关文章

升级鸿蒙系统效果,鸿蒙系统初体验 全方位体验升级[多图]

鸿蒙系统是近期华为发布的&#xff0c;这个的话&#xff0c;在更新了以后&#xff0c;就能够看到了&#xff0c;不过只是对于某些适配机型来说是这样&#xff0c;其他的话&#xff0c;是没有的&#xff0c;很多用户都十分的好奇&#xff0c;也是在观望当中&#xff0c;这个的话…

android6.1内存,iPhone 6为何坚持1GB内存?安卓太坑爹!

这个问题说简单也简单&#xff0c;说复杂也很复杂。有人该回答了&#xff1a;“是苹果优化好呗&#xff01;”说苹果好&#xff0c;里面本身就带着几分“Android呵呵”的意思。而事实似乎并非如此。iOS设备采取了与Android不同的内存垃圾回收机制&#xff0c;因此两者对运存容量…

iPad Pro 11 英寸(2021 年)评测:比笔记本电脑更奢华

Apple 的高端中型 iPad 还没有完全准备好取代您的 MacBook&#xff0c;但我们不否认它是一款出色的平板电脑。那么 11 英寸iPad Pro具体性能如何呢&#xff1f;它能替代MacBook吗&#xff1f; iPad Pro 11in (2021, M1) 全面评测 苹果公司于 2020 年夏季开始&#xff0c;处理器…

牛客题解-------BC99:正方形图案

目录 一、题目相关 二、题目链接 三、题目 题目描述&#xff1a; 输入 输出 样例 四、题目分析 五、AC参考代码 六、共勉 一、题目相关 在对于初学C语言的我来说&#xff0c;对于图形打印一直都有一种未知的恐惧&#xff0c;大家是否跟我一样在开始对于图形的打印只…

Python爬虫:抓取表情包的下载链接

Python爬虫:抓取表情包的下载链接 1. 前言2. 具体实现3. 实现代码 1. 前言 最近发现了一个提供表情包的网址&#xff0c;觉得上面的内容不错&#xff0c;于是就考虑用Python爬虫获取上面表情包的下载链接。整体而言&#xff0c;实现这个挺简单的&#xff0c;就是找到提供表情包…

步入React正殿 - 事件处理

目录 扩展学习资料 React事件和DOM事件 和传统DOM事件处理异同 this关键字的处理 this关键字 在JSX中使用bind方法 在构造函数中使用bind方法 使用箭头函数【推荐】 向事件处理程序传递参数【不跨组件】 向父组件传递参数 /src/App.js /src/components/listItem.jsx…

微信对接系列——微信自动退款

业务背景 关于微信自动退款串接背景基于酷客多多商户系统&#xff0c;系统组成主要有前端小程序、商家后台管理系统、运营商系统等 业务流程 退款单状态&#xff1a;待退款、退款中、退款完成、自动退款失败等 由于微信申请退款接口接受请求后不会立即进行退款处理&#xf…

基于grpc从零开始搭建一个准生产分布式应用(1) - 开始准备

开始前必读&#xff1a;​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ 本来笔者并不想开设这个系列&#xff0c;因为工作量比较大&#xff0c;另外此专题的技术点也偏简单。最近复盘了下最近的工作&#xff0c;发现一个问题就是各个互联网大厂一般都会有…

微信小程序开发(十)小程序支付-查询退款

应用场景 提交退款申请后&#xff0c;通过调用该接口查询退款状态。退款有一定延时&#xff0c;用零钱支付的退款20分钟内到账&#xff0c;银行卡支付的退款3个工作日后重新查询退款状态。 接口说明 这里退款还是根据商户订单号-out_trade_no去微信那边查询 代码实现 /** 根…

微信中的这个功能尽早设置,即使转错账也能及时收回!

生活在快节奏的我们&#xff0c;是离不开互联网的&#xff0c;出门在外&#xff0c;旅行&#xff0c;购物&#xff0c;点餐等等都离不开手机中&#xff0c;手机中最不可能缺少的两款APP就是微信和支付宝&#xff0c;不管是微信&#xff0c;还是支付宝这两款软件在大家心目中是不…

Java - 微信支付

首先贴出官方文档&#xff0c;关于介绍&#xff0c;场景&#xff0c;参数说明&#xff0c;可以直接看文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/api/index.html 一. APP支付 官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter9_1…

JAVA微信退款(JSAPI支付)

上一章咱们介绍了微信支付整个流程&#xff0c;这章就趁热打铁地整理下微信退款&#xff08;JSAPI支付&#xff09;相关的知识&#xff0c;为这几章的微信支付画上一个句号把。 前提&#xff1a;从微信公众号那边获取appid&#xff0c;mchid&#xff0c;paternerKey三个参数备…

实例:用C#.NET手把手教你做微信公众号开发(20)--使用微信支付线上收款:jsapi方式

在做线上、线下销售时&#xff0c;可以使用微信便捷支付&#xff0c;通过微信公众号收款有很多种收款方式&#xff0c;如下图&#xff1a; 今天我们来讲一下jsapi支付&#xff0c;场景就是在微信内打开某个页面&#xff0c;完成在线支付&#xff0c;同样一个网页&#xff0c;使…

基于时态差分法的强化学习:Sarsa和Q-learning

时态差分法&#xff08;Temporal Difference, TD&#xff09;是一类在强化学习中广泛应用的算法&#xff0c;用于学习价值函数或策略。Sarsa和Q-learning都是基于时态差分法的重要算法&#xff0c;用于解决马尔可夫决策过程&#xff08;Markov Decision Process, MDP&#xff0…

微信小游戏直播在Android端的跨进程渲染推流实践

本文由微信开发团队工程师“virwu”分享。 1、引言 近期&#xff0c;微信小游戏支持了视频号一键开播&#xff0c;将微信升级到最新版本&#xff0c;打开腾讯系小游戏&#xff08;如跳一跳、欢乐斗地主等&#xff09;&#xff0c;在右上角菜单就可以看到发起直播的按钮一键成…

辞职信微信html,微信退款处理.html

&#xfeff;微信退款处理 $axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; }; $axure.utils.getOtherPath function() { return resources/Other.html; }; $axure.utils.getReloadPath function() { return resources/reload.h…

php微信退款到银行卡,微信支付PHP开发教程七查询退款

重要&#xff1a;本文最后更新于2019-06-07 08:47:57&#xff0c;某些文章具有时效性&#xff0c;若有错误或已失效&#xff0c;请在下方留言或联系代码狗。 上一篇我们已经学会了如何使用微信支付的退款接口发起退款请求&#xff0c;并且能判断退款成功与否&#xff0c;为了安…

题解:ABC276E - Round Trip

题解&#xff1a;ABC276E - Round Trip 题目 链接&#xff1a;Atcoder。 链接&#xff1a;洛谷。 难度 算法难度&#xff1a;普及。 思维难度&#xff1a;提高。 调码难度&#xff1a;提高。 综合评价&#xff1a;困难。 算法 bfs。 思路 从起点周围四个点中任选两…

北京冬奥会 向世界展示了什么

01 北京冬奥会让全球的目光&#xff0c;再次聚焦到中国。大家深刻感知到了一个巨大的变化&#xff1a;从过去中国需要融入世界&#xff0c;需要走向全球化&#xff0c;到今天世界需要中国&#xff0c;中国做好了准备。从2008年北京奥运会&#xff0c;到2022年北京冬奥会&#…

我们该不该旗帜鲜明地反对李彦宏当选院士?

这几天&#xff0c; 中国工程院对外公布2019年 院士增选候选人&#xff0c;百度董事长兼 首席执行官 李彦宏位列其中。尽管&#xff0c;最终有望从531名候选人中脱颖而出的&#xff0c;可算凤毛麟角。但是&#xff0c;针对李彦宏的候选&#xff0c;还是有网友喊出了“旗帜鲜明地…