题目地址:
https://leetcode.com/problems/two-sum-bsts/
给定两棵二叉搜索树,再给定一个数 x x x,问两棵BST里是否各自存在一个节点使得它们之和恰好等于 x x x。
在两个序列上做这件事是容易的,可以直接用对撞双指针(一个指针指向第一个数组的开头,另一个指向第二个数组的结尾)。现在要在两棵BST上做,思路是一样的,可以先实现二叉树的中序遍历的迭代器,以及逆序中序遍历的迭代器,然后就可以当成数组的情况来做了。
中序遍历迭代器的写法是用栈,初始化的时候,先将树根所在的左链push进栈,每次弹出的节点即为下一个走到的节点,走到之后,将其左儿子所在的左链push进栈(如果有的话)。逆序中序遍历迭代器的写法和正序中序遍历迭代器的写法是对称的。
代码如下:
class Solution {
public:
struct Ite {
stack<TreeNode *> stk;
bool desc;
Ite(TreeNode *root, bool desc) : desc(desc) {
while (root) {
stk.push(root);
root = !desc ? root->left : root->right;
}
}
// 重载bool()运算符
operator bool() { return stk.size(); }
// 重载dereference运算符
int operator*() { return stk.top()->val; }
// 重载前置++运算符
Ite &operator++() {
auto t = stk.top(); stk.pop();
if (!desc) {
auto right = t->right;
while (right) {
stk.push(right);
right = right->left;
}
} else {
auto left = t->left;
while (left) {
stk.push(left);
left = left->right;
}
}
return *this;
}
};
bool twoSumBSTs(TreeNode *r1, TreeNode *r2, int t) {
Ite it1(r1, false), it2(r2, true);
while (it1 && it2) {
int x1 = *it1, x2 = *it2;
if (x1 + x2 < t) ++it1;
else if (x1 + x2 > t) ++it2;
else return true;
}
return false;
}
};
时间复杂度 O ( n 1 + n 2 ) O(n_1+n_2) O(n1+n2),空间 O ( h 1 + h 2 ) O(h_1+h_2) O(h1+h2)。