给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
思路
1.二叉搜索树的中序遍历是递增序列,反中序遍历(先找右节点)是递减数组
2.在有序数组中找两数之和为k时,可以同时比较最大最小值
大于k,从右端找更小值;
小于k,从左端找更大值;
代码结合以上两点:
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
bool findTarget(TreeNode* root, int k) {
TreeNode* cur_left=root;
TreeNode* cur_right=root;
stack<TreeNode*> st_left; //存放中序遍历节点,从小到大
stack<TreeNode*> st_right; //存放反中序遍历节点 ,从大到小
int l,r;
while(cur_left||cur_right||!st_left.empty()||!st_right.empty())
{
if(cur_left)
{
st_left.push(cur_left);//记录中序节点
r=cur_left->val;
cur_left=cur_left->left;
}
if(cur_right)
{
st_right.push(cur_right);
l=cur_right->val;
cur_right=cur_right->right;
if(l+r==k&&l!=r) //遍历同时进行判断
return true;
}
if(!cur_right&&!cur_left)
{
cur_left=st_left.top();//中序遍历最左边节点,必定是最小节点
cur_right=st_right.top(); //反中序遍历最右边节点,必定是最大节点
if(cur_left==cur_right)
break;
l=cur_left->val;
r=cur_right->val;
if(l+r==k)
return true;
else if(l+r>k)
{
//需要更小值,左边节点不变,右边进行反中序遍历,找更小的值
cur_left=NULL;
cur_right=cur_right->left;
st_right.pop();
}
else
{
//需要更大值,右边节点不变,左边进行中序遍历,找更大的值
cur_right=NULL;
cur_left=cur_left->right;
st_left.pop();
}
}
}
return false;
}
};