算法挑战59: 二叉搜索树最近节点查询

2 阅读1分钟

题目:

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

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

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

思路:

这道题确实有点难搞

我们得先提取题目的意思

给了一个数组, 数组里面每一个元素都是target

这样的话, 就需要遍历n次

然后每次都在二叉树中寻找两个边界值

大于target的最小值和小于target的最大值, 如果等于target的话, 直接赋值后返回就可以了

这是我的思路, 有三个测试过不去

然后就去找更优的题解了


为了加快回答询问的速度,可以通过一次 二叉树的中序遍历 得到有一个严格递增数组 a,再在 a 上做二分查找,就可以做到单次询问 O(logn) 的时间了。

代码:

我的超时题解:

var closestNodes = function (root, queries) {
    function dfs(root, taget, arr) {
        if (!root) return;
        if (root.val < taget) {
            arr[0] = Math.max(arr[0], root.val);
        } else if (root.val > taget) {
            arr[1] = Math.min(arr[1], root.val);
        } else {
            arr[0] = root.val;
            arr[1] = root.val;
            return;
        }

        if (root.val < taget) {
            return dfs(root.right, taget, arr);
        } else {
            return dfs(root.left, taget, arr);
        }

    }
    let res = new Array(queries.length).fill(null).map(() => [-Infinity, Infinity]);
    //遍历queries数组, 每次遍历都在树中找值
    for (let i = 0; i < queries.length; i++) {
        let x = queries[i];
        dfs(root, x, res[i]);
    }

    for (let i = 0; i < res.length; i++) {
        if (res[i][0] === -Infinity) res[i][0] = -1;
        if (res[i][1] === Infinity) res[i][1] = -1;
    }
    return res;
};