2476.二叉搜索树最近节点查询

题目描述

给你一个 二叉搜索树 的根节点 root ,和一个由正整数组成、长度为 n 的数组 queries 。

请你找出一个长度为 n 的 二维 答案数组 answer ,其中 answer[i] = [mini, maxi] :

mini 是树中小于等于 queries[i] 的 最大值 。如果不存在这样的值,则使用 -1 代替。
maxi 是树中大于等于 queries[i] 的 最小值 。如果不存在这样的值,则使用 -1 代替。
返回数组 answer 。

示例 1 :

 

输入:root = [6,2,13,1,4,9,15,null,null,null,null,null,null,14], queries = [2,5,16]
输出:[[2,2],[4,6],[15,-1]]
解释:按下面的描述找出并返回查询的答案:
- 树中小于等于 2 的最大值是 2 ,且大于等于 2 的最小值也是 2 。所以第一个查询的答案是 [2,2] 。
- 树中小于等于 5 的最大值是 4 ,且大于等于 5 的最小值是 6 。所以第二个查询的答案是 [4,6] 。
- 树中小于等于 16 的最大值是 15 ,且大于等于 16 的最小值不存在。所以第三个查询的答案是 [15,-1] 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/closest-nodes-queries-in-a-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

首先需要通过深度优先搜素把二叉排序树中结点的值依次存入列表ls中,按照左根右的顺序深度优先搜素会得到一个有序的列表

接下来的每次查询操作只需要用二分查找在ls中找x,如果x在ls中出现了,则min=max=x本身,如果x未在ls中出现,最后while循环结束时,left对应的下标就是该次查找x应该在ls中插入的位置,那么min=ls[left-1],max=ls[left],那么就需要判断当前的left是否为0、len(ls),因为当left==0时,前面就不存在比它小的元素,需要返回[-1,ls[left]],如果left==len(ls),就说明后面不存在比它大的元素,需要返回[ls[left-1],-1],除了以上两点边界情况,其他的都可以直接返回[ls[left-1],ls[left]]

注:设置一个标记flag,初始时为true,如果当前查询x存在ls中直接将[x,x]插入ans后,后序就不需要再次判断left位置情况了,所以那些通过break出来的flag会被置为false,外层for循环判断后直接continue进行下一次的查询。

代码

# 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 closestNodes(self, root: Optional[TreeNode], queries: List[int]) -> List[List[int]]:
        ls=[]
        ans=[]
        def dfs(root):
            if root.left:
                dfs(root.left)
            ls.append(root.val)
            if root.right:
                dfs(root.right)
            return 
        dfs(root)
        for x in queries:
            left,right=0,len(ls)-1
            flag=True
            while left<=right:
                mid=(left+right)//2
                if ls[mid]>x:
                    right=mid-1
                elif ls[mid]<x:
                    left=mid+1
                else:
                    ans.append([x,x])
                    flag=False
                    break
            if not flag:
                continue
            if left==len(ls):
                ans.append([ls[left-1],-1])
            elif left==0:
                ans.append([-1,ls[left]])
            else:
                ans.append([ls[left-1],ls[left]])
        return ans

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值