二叉搜索树——两数之和

给定一个二叉搜索树的根节点,问是否存在两个元素之和为k。

节点定义:

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) {}
};
定义

我的解法:

无脑的利用中序遍历得到递增的unordered_set数组,然后用遍历auto:set,i和count(k-i)即可

class Solution
{
public:
    unordered_set<int> s;
    void get(TreeNode *n)
    {
        if (!n)
            return;
        get(n->left);
        s.insert(n->val);
        get(n->right);
    }
    bool findTarget(TreeNode *root, int k)
    {
        get(root);
        for (auto i : s)
            if (s.find(k - i) != s.end() && s.find(i) != s.find(k - i))
                return true;
        return false;
    }
};
无脑简短

进阶一点:

得到递增的vector数组后用二分来搜索(顺便复习一下二分)

class Solution
{
public:
    vector<int> vc;
    void get(TreeNode *n)
    {
        if (!n)
            return;
        if (n->left)
            get(n->left);
        vc.emplace_back(n->val);
        if (n->right)
            get(n->right);
    }
    int find(int x)
    {
        int l = 0, r = vc.size() - 1;
        while (l + 1 < r)
        {
            int mid = (l + r) >> 1;
            if (vc[mid] <= x)
                l = mid;
            else
                r = mid;
        }
        return l;
    }
    bool findTarget(TreeNode *root, int k)
    {
        get(root);
        sort(vc.begin(), vc.end());
        for (int i = 0; i < vc.size(); ++i)
        {
            int j = find(k - vc[i]);
            if (vc[i] + vc[j] == k && i != j)
                return true;
        }
        return false;
    }
};
二分

然后就是他解:

【归根于在读入的时候同时利用set.count,还有本来是双指针或者双dfs的处理给优化成了set+dfs】

class Solution
{
public:
    bool findTarget(TreeNode *root, int k)
    {
        if (!root)
            return false;
        unordered_set<int> temp;
        stack<TreeNode *> s;
        s.push(root);
        while (!s.empty())
        {
            auto node = s.top();
            s.pop();
            if (temp.count(node->val))
                return true;
            temp.insert(k - node->val);
            if (node->left)
                s.push(node->left);
            if (node->right)
                s.push(node->right);
        }
        return false;
    }
};
栈循环+set处理
class Solution
{
    unordered_set<int> us;
    bool dfs(TreeNode *root, int k)
    {
        if (us.count(k - root->val))
            return true;
        us.insert(root->val);
        bool res;
        if (root->left && dfs(root->left, k))
            return true;
        if (root->right && dfs(root->right, k))
            return true;
        return false;
    };
public:
    bool findTarget(TreeNode *root, int k)
    {
        if (root)
            return dfs(root, k);
        return false;
    }
};
set+dfs

----------------------------------------------------------------------------------------

从时间复杂度来分析都是他解更高,代码也更简洁一些,慢慢优化转换思路吧。

posted @ 2022-02-28 18:40  Renhr  阅读(32)  评论(0)    收藏  举报