给定一个二叉树。找到树中的两个元素,使他们的和为k。假设树是平衡的。
Given a binary tree. Find two numbers in the tree whose sum is k. If there are no such elements, state so. Assume that the tree is balanced.
如果树是bst,即若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
对BST进行中序遍历得到一个递增的数字串。对于递增序列找这两个元素很简单。我的前面一片blog写到过:http://blog.csdn.net/f81892461/article/details/8583519
简单来说就是从序列的头和尾进行遍历,找出和为k的数。
如果不是序列,是BST呢?我们能从最左端的节点和最右端的节点进行遍历。如果(a+b)>k,需要找到第一个比b小的数,即找b的左子树的最右端(如果b有左子树),没有左子树时就是b的父节点。当a+b<k时,增大a,找到a的右子树的最左端(如果a有右子树)。当a>=b时表示遍历完所有的数,stop。
Is it a bst? If yes,
We can start from left most node and the right most node in the bst. It (a+b) > k then iterate right to left by one (next smaller value) else iterate left pointer to right by one (next bigger value). Stop at a >= b.
We have to do it iteratively:
a = b = root;
while (a.left) {//找到最左端的节点a,a的左节点为空
astack.push(a)//用栈来存储 方便当a没有右子树时 出栈求出第一个value大于a的节点 对于b也是如此了
a = a.left
}
while (b.right) {//找到最右端的节点b,b的右节点为空
bstack.push(b)
b = b.right
}
while (a.value < b.value) {
if (a.value + b.value == k) found!
if (a.value + b.value < k) {//需要增大a.value的值 找到第一个比a.value大的节点
if (a.right){
a = a.right
while (a.left) {
astack.push(a)
a = a.left
}//a的右子树为空时 出栈
} else a = astack.pop()
} else {//减小b.value的值 找到第一个小于value的节点
if (b.left){
b = b.left
while (b.right) {
bstack.push(b)
b = b.right
}//b的左子树为空时 出栈
} else b = bstack.pop()
}
}
如果为普通的二叉树,选择一个节点a,从树种找出k-a.value。这样时间复杂度为O(n^2).为了防止重复,对处理过的节点进行标记。这里
But if it is a binary tree, I'm afraid it will be O(n^2).
Pick a node, find the (k-root->val) in the rest of the tree. and do it for all the nodes until you find a solution.