列表

详情


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

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

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

返回数组 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] 。

示例 2 :

输入:root = [4,null,9], queries = [3]
输出:[[-1,4]]
解释:树中不存在小于等于 3 的最大值,且大于等于 3 的最小值是 4 。所以查询的答案是 [-1,4] 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
/** * Definition for a binary tree node. * 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: vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) { } };

rust 解法, 执行用时: 83 ms, 内存消耗: 21.4 MB, 提交时间: 2024-02-24 10:06:27

// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//     TreeNode {
//       val,
//       left: None,
//       right: None
//     }
//   }
// }
use std::rc::Rc;
use std::cell::RefCell;

impl Solution {
    pub fn closest_nodes(root: Option<Rc<RefCell<TreeNode>>>, queries: Vec<i32>) -> Vec<Vec<i32>> {
        fn dfs(node: Option<&Rc<RefCell<TreeNode>>>, a: &mut Vec<i32>) {
            if let Some(x) = node {
                let x = x.borrow();
                dfs(x.left.as_ref(), a);
                a.push(x.val);
                dfs(x.right.as_ref(), a);
            }
        }
        let mut a = Vec::new();
        dfs(root.as_ref(), &mut a);

        let n = a.len();
        let mut ans = Vec::new();
        for q in queries {
            let mut j = a.partition_point(|&x| x < q);
            let mx = if j < n { a[j] } else { -1 };
            let mn = if j < n && a[j] == q { q } else if j > 0 { a[j - 1] } else { -1 };
            ans.push(vec![mn, mx]);
        }
        ans
    }
}

javascript 解法, 执行用时: 535 ms, 内存消耗: 108.8 MB, 提交时间: 2024-02-24 10:06:06

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number[]} queries
 * @return {number[][]}
 */
var closestNodes = function(root, queries) {
    const a = [];
    function dfs(node) {
        if (node === null) {
            return;
        }
        dfs(node.left);
        a.push(node.val);
        dfs(node.right);
    }
    dfs(root);

    const n = a.length;
    const ans = [];
    for (const q of queries) {
        let j = lowerBound(a, q);
        const mx = j < n ? a[j] : -1;
        if (j === n || a[j] !== q) { // a[j]>q, a[j-1]<q
            j--;
        }
        const mn = j >= 0 ? a[j] : -1;
        ans.push([mn, mx]);
    }
    return ans;
};

// 见 https://www.bilibili.com/video/BV1AP41137w7/
var lowerBound = function(a, target) {
    let left = -1, right = a.length; // 开区间 (left, right)
    while (left + 1 < right) { // 区间不为空
        const mid = Math.floor((left + right) / 2);
        if (a[mid] >= target) {
            right = mid; // 范围缩小到 (left, mid)
        } else {
            left = mid; // 范围缩小到 (mid, right)
        }
    }
    return right;
}

cpp 解法, 执行用时: 336 ms, 内存消耗: 152.3 MB, 提交时间: 2023-08-09 19:52:42

/**
 * Definition for a binary tree node.
 * 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:
    vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
        if(!root)return{{-1,-1}};
        vector<int>v;
        vector<vector<int>>ans;
        queue<TreeNode*> q;
        q.push(root);
        //下面这个while循环就是宽搜框架
        while(q.size()){
            int len = q.size();//这个一层的元素个数
            for(int i = 0 ;i<len ;i++){
                auto t = q.front();//每次拿到这个一行的第i个元素
                v.push_back(t->val);
                q.pop();
                //接下来,我们来扩展一下队列,为下一层宽搜作准备
                if(t->left)q.push(t->left);
                if(t->right)q.push(t->right);
            }
        }
        sort(v.begin(),v.end());//我们模拟的单调队列
        for(int i = 0 ;i<queries.size();i++){
            
            int l=0,r=v.size()-1;//队头和队尾
            while(l<r){//求>=queries[i]的最小值
                int mid = l + r >>1;
                if(v[mid]>=queries[i])r=mid;
                else l = mid +1;
            }
            int tmp = r;
            l=0,r=v.size()-1;//队头和队尾
            while(l<r){//求<=queries[i]的最大值
                int mid = l + r +1 >>1;
                if(v[mid]<=queries[i])l=mid;
                else r = mid -1;
            }
            int left=v[l],right=v[tmp];
            if(v[tmp]<queries[i])right = -1;
            if(v[l]>queries[i])left = -1;
            ans.push_back({left,right});
        }
        return ans;
        
    }
};

java 解法, 执行用时: 83 ms, 内存消耗: 101.4 MB, 提交时间: 2023-08-09 19:52:09

class Solution {
    List<Integer> sort = new ArrayList<>();
    List<List<Integer>> ans = new ArrayList<>();
    public List<List<Integer>> closestNodes(TreeNode root, List<Integer> q) {
        dfs(root);
        for (int x : q) {
            int idx = search(x), a = -1, b = -1, c = sort.get(idx);
            if (c == x) {a = b = sort.get(idx);}
            if (c > x && idx != 0) {a = sort.get(idx - 1); b = c;}
            else if(c > x && idx == 0) b = c;
            else a = c;
            ans.add(Arrays.asList(a, b));
        }
        return ans;
    }
    int search(int x) { //寻找大于等于的元素下标
        int l = 0, r = sort.size() - 1;
        while (l < r) {
            int mid = (l + r) / 2;
            if (sort.get(mid) >= x) r = mid;
            else l = mid + 1;
        }
        return r;
    }
    void dfs(TreeNode root) {
        if (root == null) return;
        dfs(root.left);
        sort.add(root.val);
        dfs(root.right);
    }
}

golang 解法, 执行用时: 320 ms, 内存消耗: 52.7 MB, 提交时间: 2023-08-09 19:49:49

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func closestNodes(root *TreeNode, queries []int) [][]int {
	a := []int{}
	var dfs func(*TreeNode)
	dfs = func(o *TreeNode) {
		if o == nil {
			return
		}
		dfs(o.Left)
		a = append(a, o.Val)
		dfs(o.Right)
	}
	dfs(root)

	ans := make([][]int, len(queries))
	for i, q := range queries {
		min, max := -1, -1
		// 这是怎么转换的,可以看我上面贴的视频链接
		j := sort.SearchInts(a, q+1) - 1
		if j >= 0 {
			min = a[j]
		}
		j = sort.SearchInts(a, q)
		if j < len(a) {
			max = a[j]
		}
		ans[i] = []int{min, max}
	}
	return ans
}

python3 解法, 执行用时: 732 ms, 内存消耗: 160.5 MB, 提交时间: 2023-08-09 19:49:12

# 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]]:
        a = []
        def dfs(o: Optional[TreeNode]) -> None:
            if o is None: return
            dfs(o.left)
            a.append(o.val)
            dfs(o.right)
        dfs(root)

        ans = []
        for q in queries:
            j = bisect_right(a, q)
            min = a[j - 1] if j else -1
            j = bisect_left(a, q)
            max = a[j] if j < len(a) else -1
            ans.append([min, max])
        return ans

上一题