QUESTION
easy
题目描述
给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
案例 1:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
输出: True
案例 2:
输入:
5
/ \
3 6
/ \ \
2 4 7
Target = 28
输出: False
说明
无
SOLUTION
这道题思可太多了
方法一
中序遍历 + 二分查找
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
vector<int> nums;
inorder(root, nums);
for(int i = 0; i < nums.size(); i++){
if(nums[i]> 0 && nums[i] >= k) return false;
if(binarySearch(nums, i+1, k - nums[i])!= -1) return true;
}
return false;
}
void inorder(TreeNode* node, vector<int> &nums){
if(node == nullptr) return;
inorder(node->left, nums);
nums.push_back(node->val);
inorder(node->right, nums);
}
int binarySearch(vector<int> &nums, int l, int k){
int r = nums.size() - 1;
while(l <= r){
int mid = l + (r - l) / 2;
if(nums[mid] < k) l = mid + 1;
else if(nums[mid] > k) r = mid - 1;
else return mid;
}
return -1;
}
};
方法二
同方法一,也是先中序遍历得到升序数组。但找数字使用双指针的办法。
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
vector<int> nums;
inorder(root, nums);
int i = 0, j = nums.size() - 1;
while(i < j){
if(nums[i] + nums[j] == k) return true;
nums[i] + nums[j] < k ? ++i : --j;
}
return false;
}
void inorder(TreeNode* node, vector<int>& nums) {
if (node == nullptr) return;
inorder(node->left, nums);
nums.push_back(node->val);
inorder(node->right, nums);
}
};
方法三
用一个有序的集合来解决。思路与方法一相同
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
set<int> s;
inorder(root, s);
for(auto e : s){
if(e > 0 && e >= k) return false;
if(k != e+e && s.count(k - e)) return true;
}
return false;
}
void inorder(TreeNode* node, set<int> &s){
if(node == nullptr) return;
inorder(node->left, s);
s.insert(node->val);
inorder(node->right, s);
}
};
方法四
还是利用集合的性质,但是这次我们用非有序的集合,同时动态地递归判断
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
unordered_set<int> st;
return preorder(root, k, st);
}
bool preorder(TreeNode* node, int k, unordered_set<int>& st) {
if (node == nullptr) return false;
if (st.count(k - node->val)) return true;
st.insert(node->val);
return preorder(node->left, k, st) || preorder(node->right, k, st);
}
};