题目
给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
题目链接
示例
示例1
输入:
5
/
3 6
/
2 4 7
Target = 9
输出: True
示例2
输入:
5
/
3 6
/
2 4 7
Target = 28
输出: False
题目分析
BST,二叉搜索树。二叉搜索树的中序遍历是升序排列,因此我们可以先对该树中序遍历,然后把遍历每一步的结点值放入一个数组中,再从数组中找到是否有符合目标值的两数之和。
树的中序遍历:
void MidOrder(tree root){
MidOrder(root->left);
visit(root);
MidOrder(root->right);
}
在升序数组中找是否有符合目标值target
可以采用如下方法:
int left = 0;
int right = length - 1;
while (left != right){
int temp = a[left] + a[right];
if (temp < target){
left++;
}else if (temp > target){
right--;
}else {
return true;
}
}
return false;
为了方便进行数组的插入操作,我们使用了STL容器中的vector来简化程序。vector常用操作如下:
// 定义vector
vector<int> res;
// 获得数组元素个数
length = res.size();
// 迭代器的定义,STL容器的遍历一般都通过迭代器来实现(vector也可以通过下表实现随机遍历)
vector<int>::iterator it = res.begin();
// 插入操作
res.push_back(x);
小tips:C++的新特性允许我们使用auto
来遍历STL容器,效率等同于迭代器,十分方便,使用方法为:
vector<int> res;
for (auto temp : res){
printf("%d ", temp);
}
总结一下,该题的思路就是把不能随机遍历的树变为有序的数组,方便进行随机遍历。
题目解答
class Solution {
public:
vector<int> res;
void MidOrder(vector<int> &res, TreeNode* root){
if (root == NULL) return ;
MidOrder(res, root->left);
res.push_back(root->val);
MidOrder(res, root->right);
}
bool findTarget(TreeNode* root, int k) {
MidOrder(res, root);
vector<int>::iterator left = res.begin();
vector<int>::iterator right = res.end() - 1;
while (left != right){
int temp = *left + *right;
// printf("%d %d %dn", temp, *left, *right);
if (temp < k){
left++;
}else if (temp > k){
right--;
}else {
return true;
}
}
return false;
}
};