[LeetCode] 653. Two Sum IV - Input is a BST 两数之和之四 - 输入是二叉搜索树

本文探讨了在二叉搜索树(Binary Search Tree, BST)中寻找两个节点使其值之和等于给定目标值的问题。提供了多种解决方案,包括使用哈希表、排序数组以及二分查找等方法,并分析了每种方法的时间复杂度和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.

Example 1:

Input:

    5
   / \
  3   6
 / \   \
2   4   7

Target = 9

Output: True
Example 2:

Input:

    5
   / \
  3   6
 / \   \
2   4   7

Target = 28

Output: False

思路:

Two Sum的变种题,这次输入的是一个二叉树,还是用HashMap,然后遍历二叉树,用之前的方法找就行了。

还有一种方法是利用BST的性质,进行查找。

Java:

This method also works for those who are not BSTs. The idea is to use a hashtable to save the values of the nodes in the BST. Each time when we insert the value of a new node into the hashtable, we check if the hashtable contains k - node.val.

Time Complexity: O(n), Space Complexity: O(n).

public boolean findTarget(TreeNode root, int k) {
        HashSet<Integer> set = new HashSet<>();
        return dfs(root, set, k);
    }
    
    public boolean dfs(TreeNode root, HashSet<Integer> set, int k){
        if(root == null)return false;
        if(set.contains(k - root.val))return true;
        set.add(root.val);
        return dfs(root.left, set, k) || dfs(root.right, set, k);
    }

Java:

The idea is to use a sorted array to save the values of the nodes in the BST by using an inorder traversal. Then, we use two pointers which begins from the start and end of the array to find if there is a sum k.

Time Complexity: O(n), Space Complexity: O(n).

    public boolean findTarget(TreeNode root, int k) {
        List<Integer> nums = new ArrayList<>();
        inorder(root, nums);
        for(int i = 0, j = nums.size()-1; i<j;){
            if(nums.get(i) + nums.get(j) == k)return true;
            if(nums.get(i) + nums.get(j) < k)i++;
            else j--;
        }
        return false;
    }
    
    public void inorder(TreeNode root, List<Integer> nums){
        if(root == null)return;
        inorder(root.left, nums);
        nums.add(root.val);
        inorder(root.right, nums);
    }

Java:

The idea is to use binary search method. For each node, we check if k - node.val exists in this BST.

Time Complexity: O(nh), Space Complexity: O(h). h is the height of the tree, which is logn at best case, and n at worst case.

    public boolean findTarget(TreeNode root, int k) {
        return dfs(root, root,  k);
    }
    
    public boolean dfs(TreeNode root,  TreeNode cur, int k){
        if(cur == null)return false;
        return search(root, cur, k - cur.val) || dfs(root, cur.left, k) || dfs(root, cur.right, k);
    }
    
    public boolean search(TreeNode root, TreeNode cur, int value){
        if(root == null)return false;
        return (root.val == value) && (root != cur) 
            || (root.val < value) && search(root.right, cur, value) 
                || (root.val > value) && search(root.left, cur, value);
    }

Java: 

public class Solution {
    public boolean findTarget(TreeNode root, int k) {
        List<Integer> list = new ArrayList<>();
        inorder(root, list);
        int i = 0;
        int j = list.size() - 1;
        while (i < j) {
            int sum = list.get(i) + list.get(j);
            if (sum == k) {
                return true;
            }
            else if (sum < k) {
                i++;
            }
            else {
                j--;
            }
        }
        return false;
    }

    public List<Integer> inorder(TreeNode root, List<Integer> list) {
        Stack<TreeNode> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            list.add(root.val);
            root = root.right;
        }
        return list;
    }
}

Java:

public class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Set<Integer> candidates = new HashSet<>();
        Stack<TreeNode> stack = new Stack<>();
        while (!stack.empty() || root != null) {
            if (root != null) {
                int val = root.val;
                if (candidates.contains(val)) {
                    return true;
                } else {
                    candidates.add(k - val);
                }
                stack.add(root);
                root = root.left;
            } else {
                TreeNode node = stack.pop();
                root = node.right;
            }
        }
        return false;
    }
}  

Python: 递归遍历BST + Two Sum

class Solution(object):
    def findTarget(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: bool
        """
        self.dset = set()
        self.traverse(root)
        for n in self.dset:
            if k - n != n and k - n in self.dset:
                return True
        return False
    def traverse(self, root):
        if not root: return
        self.dset.add(root.val)
        self.traverse(root.left)
        self.traverse(root.right)

Python: wo, 160 ms, faster than 9.23% of Python online submissions

class Solution(object):
    def findTarget(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: bool
        """
        nums = []
        self.dfs(root, nums)
        lookup = []

        for num in nums:
            if k - num in lookup:
                return True
            lookup.append(num)
        return False    
                
        
    def dfs(self, root, res):
        if not root:
            return
        res.append(root.val)
        self.dfs(root.left, res)
        self.dfs(root.right, res)

Python: 递归遍历BST + 利用BST性质进行检索

class Solution(object):
    def findTarget(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: bool
        """
        self.root = root
        self.k = k
        return self.findNumber(root)
    def findNumber(self, root):
        if not root: return False
        node = self.root
        n = self.k - root.val
        if n != root.val:
            while node:
                if node.val == n: return True
                if n > node.val: node = node.right
                else: node = node.left
        return self.findNumber(root.left) or self.findNumber(root.right)

Python:

class Solution:
    def findTarget(self, root, k):
        candidates = set()
        stack = []
        while stack or root:
            if root:
                val = root.val
                if val in candidates:
                    return True
                else:
                    candidates.add(k - val)
                stack.append(root)
                root = root.left
            else:
                node = stack.pop()
                root = node.right
        return False

C++:

bool findTarget(TreeNode* root, int k) {
        unordered_set<int> set;
        return dfs(root, set, k);
    }
    
    bool dfs(TreeNode* root, unordered_set<int>& set, int k){
        if(root == NULL)return false;
        if(set.count(k - root->val))return true;
        set.insert(root->val);
        return dfs(root->left, set, k) || dfs(root->right, set, k);
    }

C++:

bool findTarget(TreeNode* root, int k) {
        vector<int> nums;
        inorder(root, nums);
        for(int i = 0, j = nums.size()-1; i<j;){
            if(nums[i] + nums[j] == k)return true;
            (nums[i] + nums[j] < k)? i++ : j--;
        }
        return false;
    }
    
    void inorder(TreeNode* root, vector<int>& nums){
        if(root == NULL)return;
        inorder(root->left, nums);
        nums.push_back(root->val);
        inorder(root->right, nums);
    }

C++:  

bool findTarget(TreeNode* root, int k) {
        return dfs(root, root,  k);
    }
    
    bool dfs(TreeNode* root,  TreeNode* cur, int k){
        if(cur == NULL)return false;
        return search(root, cur, k - cur->val) || dfs(root, cur->left, k) || dfs(root, cur->right, k);
    }
    
    bool search(TreeNode* root, TreeNode *cur, int value){
        if(root == NULL)return false;
        return (root->val == value) && (root != cur) 
            || (root->val < value) && search(root->right, cur, value) 
                || (root->val > value) && search(root->left, cur, value);
    }

  

  

相似题目:

[LeetCode] 1. Two Sum 两数和

[LeetCode] 167. Two Sum II - Input array is sorted 两数和 II - 输入是有序的数组

[LeetCode] 170. Two Sum III - Data structure design 两数之和之三 - 数据结构设计

 

 

转载于:https://www.cnblogs.com/lightwindy/p/8481973.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值