2476. 二叉搜索树最近节点查询 【中序遍历+二分查找】 C++ 的function递归比写成类内函数慢

45 阅读2分钟

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

image.png

# 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]]:
        lis = []
        # 遍历 存储结点值
        q = deque([root])
        while q:
            cur = q.popleft()
            lis.append(cur.val)
            if cur.left:
               q.append(cur.left)
            if cur.right:
                q.append(cur.right)

        lis.sort()

        res = []
        for val in queries:
            maxVal, minVal = -1, -1
            idx = bisect_left(lis, val) # 
            if idx != len(lis):
                maxVal = lis[idx]
                if lis[idx] == val:
                    minVal = lis[idx]
                    res.append([minVal, maxVal])
                    continue 
            if idx != 0:
                minVal = lis[idx - 1]
            res.append([minVal, maxVal])

        return res

改进: 二叉搜索数的中序 遍历 即可获得 有序

image.png

python3 解法

# 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]]:
        lis = []
        # 二叉搜索树 的中序遍历  值即为有序
        def dfs(root):
            if not root:
                return 
            dfs(root.left)
            lis.append(root.val)
            dfs(root.right)

        dfs(root)
        res = []
        for val in queries:
            idx = bisect_left(lis, val) # 
            maxVal = lis[idx] if idx < len(lis) else -1
            if idx == len(lis) or lis[idx] != val:
                idx -= 1
            minVal = lis[idx] if idx >= 0 else -1
            res.append([minVal, maxVal])

        return res

————————————

/**
 * 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) {
        vector<int> arr;
        function<void(TreeNode*)> dfs = [&](TreeNode* root){
            if (root == nullptr){
                return;
            }
            dfs(root->left);
            arr.emplace_back(root->val);
            dfs(root->right);
        };

        dfs(root);

        vector<vector<int>> res;
        int n = arr.size();
        for (int q : queries){
            int idx = ranges::lower_bound(arr, q) - arr.begin();
            int maxVal = idx < n ? arr[idx] : -1;
            if (idx == n || arr[idx] != q){
                --idx;
            }
            int minVal = idx >= 0 ? arr[idx] : -1;
            res.push_back({minVal, maxVal});
        }
        return res;        
    }
};

image.png

C++ 解法

/**
 * 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 {
        vector<int> arr;

        void dfs(TreeNode* root){
            if (root == nullptr){
                return;
            }
            dfs(root->left);
            arr.emplace_back(root->val);
            dfs(root->right);
        };
public:
    vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {

        dfs(root);

        vector<vector<int>> res;
        int n = arr.size();
        for (int q : queries){
            int idx = ranges::lower_bound(arr, q) - arr.begin();
            int maxVal = idx < n ? arr[idx] : -1;
            if (idx == n || arr[idx] != q){
                --idx;
            }
            int minVal = idx >= 0 ? arr[idx] : -1;
            res.push_back({minVal, maxVal});
        }
        return res;        
    }
};