ACM 选手图解 LeetCode 二叉搜索树中的搜索

简介: ACM 选手图解 LeetCode 二叉搜索树中的搜索

大家好呀,我是搜索蛋。


今天解决二叉搜索树中的搜索,二叉搜索树查找操作练习题。


这道题本身没什么难度,就是检验大家对二叉搜索树性质的掌握程度。


咱们话不多说,赶紧开始!

640.png


   LeetCode 700:二叉搜索树中的搜索


题意


给定二叉搜索树的根节点 root 和整数值 val。


在二叉搜索树中找到节点值 = val 的节点,返回以该节点为根的子树,如果节点不存在,返回 null。


示例


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

输出:[2,1,3]

640.png



提示


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


题目解析


这道题其实就是用了二叉搜索树的性质,难度简单。


如果你不熟悉二叉搜索树,可以看我下面这篇文章:


ACM 选手带你玩转二叉搜索树!


二叉搜索树的的性质如下:


  • 若左子树不空,那左子树所有节点的值均 < 根节点的值。
  • 若右子树不空,那右子树所有节点的值均 > 根节点的值。
  • 左右子树也均为二叉搜索树。


640.png


这道题为二叉搜索树的【搜索】,其实也就是二叉搜索树的【查找】操作。


根据二叉搜索树的性质,在叉搜索树中查找一个节点,其实就 3 步:


  • 将查找的节点根节点比较,如果相等,则直接返回。
  • 如果查找的节点 < 根节点,则在左子树中递归查找。
  • 如果查找的节点 > 根节点,则在右子树中递归查找。


递归法


递归法就是老套路,根据【递归算法】文章中讲的,实现递归,需要两步:


  • 找出重复的子问题(递推公式)。
  • 终止条件。


(1) 找出重复的子问题。


这个其实在上面二叉搜索树的查找步骤中可以看出。


  • 如果查找的节点 < 根节点,则在左子树中递归查找。
  • 如果查找的节点 > 根节点,则在右子树中递归查找。

对于各个子树也都是同样的操作。

if root.val > val:
    return self.searchBST(root.left, val)
if root.val < val:
    return self.searchBST(root.right, val)

(2) 确定终止条件。


对于中止条件的话,在题中就是:


  • 如果找到,直接返回;
  • 如果 root 为空,那就没啥好找的了,直接返回 None。
if root == None:
    return None
if root.val == val:
    return root


Python 代码实现

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        if root == None:
            return None
        if root.val == val:
            return root
        if root.val > val:
            return self.searchBST(root.left, val)
        if root.val < val:
            return self.searchBST(root.right, val)


Java 代码实现


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null){
            return null;
        }
        if(root.val == val){
            return root;
        }
        if(root.val > val){
            return searchBST(root.left, val);
        }
        else{
            return searchBST(root.right, val);
        }
    }
}


本题解,最坏情况下二叉搜索树是一条链,在递归过程中每个节点都被遍历到,时间复杂度为 O(n)


此外在递归过程中调用了额外的栈空间,栈的大小取决于二叉树的高度,二叉树最坏情况下的高度为 n,所以空间复杂度为 O(n)


非递归法(迭代)


非递归法同样也是借助二叉搜索树的性质,其实也是 3 步:


  • 当 val == root.val,直接返回 root;
  • 当 val < root.val,root 就走到 root.left,继续找;
  • 当 val > root.val,root 就走到 root.right,继续找。


我们以下图为例:

640.png


第 1 步:root.val = 4,val = 2,此时 root.val > val,根据二叉树的性质,val 在左子树中寻找,此时 root = root.left。

640.png


elif root.val > val:
    root = root.left

第 2 步,此时 root.val = 2,val = 2,root.val == val,即此节点就是我们要寻找的节点,直接返回

640.png

if root.val == val:
    return root


Python 代码实现

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        if root == None:
            return None
        while root:
            if root.val == val:
                return root
            elif root.val > val:
                root = root.left
            else:
                root = root.right


Java 代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while(root != null){
            if(root.val == val){
                return root;
            }
            else if(root.val > val){
                root = root.left;
            }
            else{
                root = root.right;
            }
        }
        return null;
    }
}


本题解,最坏情况下二叉搜索树是一条链,在递归过程中每个节点都被遍历到,时间复杂度为 O(n)


非递归法没有使用额外的空间,所以空间复杂度为 O(1)


图解二叉搜索树中的搜索到这就结束辣,是不是很简单呢?其实到了现在这个地步,做题只会越来越顺。


当然辣,这只是二叉搜索树中的第一道题,还是要做好总结。


今天就到这了,记得帮我点赞 + 在看 + 转发一条龙呀,爱你们~


我是帅蛋,我们下次见!

相关文章
|
1月前
|
算法
力扣240 搜索二维矩阵II
力扣240 搜索二维矩阵II
|
3月前
|
Go
golang力扣leetcode 240.搜索二维矩阵II
golang力扣leetcode 240.搜索二维矩阵II
19 0
|
3月前
|
Go
golang力扣leetcode 79.单词搜索
golang力扣leetcode 79.单词搜索
25 0
|
12天前
Leetcode1038. 从二叉搜索树到更大和树(每日一题)
Leetcode1038. 从二叉搜索树到更大和树(每日一题)
|
2月前
|
Java
LeetCode题解-二叉搜索树中第K小的元素-Java
LeetCode题解-二叉搜索树中第K小的元素-Java
12 0
|
3月前
|
算法
代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树
代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树
30 0
|
3月前
|
算法
【Leetcode 74】搜索二维矩阵 —— 二分查找|矩阵
给你一个满足下述两条属性的`m x n`整数矩阵:每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数
|
3月前
|
存储 算法 测试技术
【深度优先】LeetCode1932:合并多棵二叉搜索树
【深度优先】LeetCode1932:合并多棵二叉搜索树
|
3月前
leetcode-1382:将二叉搜索树变平衡
leetcode-1382:将二叉搜索树变平衡
19 0
|
3月前
|
Go
golang力扣leetcode 96. 不同的二叉搜索树
golang力扣leetcode 96. 不同的二叉搜索树
16 0