给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
案例 1:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
输出: True
案例 2:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 28
输出: False
思路分析: 直接扫描整个二叉树,使用hash表记录各个元素出现的次数,然后判断k - num是否在hash表中。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
unordered_map<int, int> hashMap;
dfs(root, hashMap);
//遍历hash表
for (auto &item : hashMap){
//item.first存在,判断k - item.first是否存在
if (k != 2 * item.first && hashMap.count(k - item.first) > 0){
//第二种情况 k != 2 * item.first,则item.first、k - item.first各出现一次
return true;
}
else if (hashMap.count(k - item.first) > 0 && hashMap[item.first] > 1){
//第二种情况 k == 2 * item.first,则item.first需要出现两次
return true;
}
}
return false;
}
//中序遍历二叉树,并记录各个节点值出现的次数
void dfs(TreeNode* root, unordered_map<int, int> &hashMap){
if (root == NULL){
return;
}
dfs(root->left, hashMap);
hashMap[root->val] += 1;
dfs(root->right, hashMap);
}
};
方法二:二叉搜索树的中序遍历为递增序列,所以我们可以利用这个升序的序列寻找k。LeetCode 两数之和II
使用双指针,分别指向头、尾。如果两数之和大于target,尾指针前移,如果两数之和小于target,首指针后移。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
vector<int> nums;
dfs(root, nums);//中序遍历二叉搜索树,得到中序遍历的升序序列
//两个指针扫描nums
int left = 0, right = nums.size() - 1;
while (left < right){
int tempSum = nums[left] + nums[right];
if (tempSum == k){
return true;
}
else if (tempSum < k){
//两数之和小于k,右移左指针
left += 1;
}
else{
//两数之和大于k,左移右指针
right -= 1;
}
}
return false;
}
//中序遍历二叉树,并记录各个节点值出现的次数
void dfs(TreeNode* root, vector<int> &nums){
if (root == NULL){
return;
}
dfs(root->left, nums);
nums.push_back(root->val);
dfs(root->right, nums);
}
};