📌  相关文章
📜  二叉搜索树中具有给定总和的对的数量(1)

📅  最后修改于: 2023-12-03 15:36:03.179000             🧑  作者: Mango

二叉搜索树中具有给定总和的对的数量

问题描述

给定一个二叉搜索树和一个目标整数,找出 BST 中任意两个节点的值之和等于目标整数的个数。

例如:

给定BST如下,目标为9
      5
     / \
    3   6
   / \   \
  2   4   7

返回:2

原因:

5 + 4 = 9
3 + 6 = 9
解决方案

该问题基于 BST 的性质,可以使用 DFS 遍历二叉树,同时记录每个节点的值及其数量,将问题转化为找出具有给定总和的两个数。

以下是具体实现步骤:

  1. 深度优先遍历二叉树,记录每个节点的值及其数量

    void dfs(TreeNode* root, unordered_map<int, int>& mp) {
        if (root == nullptr) return;
    
        mp[root->val]++;
        dfs(root->left, mp);
        dfs(root->right, mp);
    }
    
  2. 对于每个节点,计算出它与其他节点的和是否等于目标整数,如果是,则将其添加到结果中

    int getPairs(TreeNode* root, int k, unordered_map<int, int>& mp) {
        if (root == nullptr) return 0;
    
        int cnt = 0;
        if (mp.find(k - root->val) != mp.end()) {
            cnt = mp[k - root->val];
            if (k - root->val == root->val) cnt--;
        }
    
        return cnt + getPairs(root->left, k, mp) + getPairs(root->right, k, mp);
    }
    
  3. 返回结果

    int findTarget(TreeNode* root, int k) {
        unordered_map<int, int> mp;
        dfs(root, mp);
        return getPairs(root, k, mp);
    }
    
时间复杂度

算法的时间复杂度为 $O(n)$,其中 $n$ 是 BST 中节点的个数,因为我们需要遍历所有节点一次。

空间复杂度

算法的空间复杂度为 $O(n)$,主要是由 DFS 使用的系统栈、哈希表和递归调用的结果产生的。

完整代码
class Solution {
public:
    void dfs(TreeNode* root, unordered_map<int, int>& mp) {
        if (root == nullptr) return;

        mp[root->val]++;
        dfs(root->left, mp);
        dfs(root->right, mp);
    }

    int getPairs(TreeNode* root, int k, unordered_map<int, int>& mp) {
        if (root == nullptr) return 0;

        int cnt = 0;
        if (mp.find(k - root->val) != mp.end()) {
            cnt = mp[k - root->val];
            if (k - root->val == root->val) cnt--;
        }

        return cnt + getPairs(root->left, k, mp) + getPairs(root->right, k, mp);
    }

    int findTarget(TreeNode* root, int k) {
        unordered_map<int, int> mp;
        dfs(root, mp);
        return getPairs(root, k, mp);
    }
};