题目:
给定一个二叉搜索树 root 和一个目标结果 k,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
算法:
方法一:用笨办法了,没有用到BST的特性
func findTarget(root *TreeNode, k int) bool {
set := make(map[int]bool)
var dfs func(*TreeNode) bool
dfs = func(node *TreeNode) bool {
if node == nil {
return false
}
if _, ok := set[k-node.Val]; ok {
return true
}
set[node.Val] = true
return dfs(node.Left) || dfs(node.Right)
}
return dfs(root)
}
方法二:BST转换为中序遍历,转换为升序数组,双指针处理升序数组
方法三:双指针处理BST
func findTarget(root *TreeNode, k int) bool {
left, right := root, root
// leftStack是降序,rightStack是升序
leftStack := []*TreeNode{left}
rightStack := []*TreeNode{right}
for left.Left != nil {
leftStack = append(leftStack, left.Left)
left = left.Left
}
for right.Right != nil {
rightStack = append(rightStack, right.Right)
right = right.Right
}
for left != right {
sum := left.Val + right.Val
if sum == k {
return true
}
if sum < k {
left = leftStack[len(leftStack) - 1]
leftStack = leftStack[:len(leftStack) - 1]
//1. left节点要出栈了,将left的右侧节点node入栈(val比left.Val大的节点)
//2. 将node的Left节点入栈
//总结:left出栈时,left.Right,left.Right.Left, ... 入栈,left.Right出栈时,left.Right.Right入栈
for node := left.Right; node != nil ; node = node.Left {
leftStack = append(leftStack, node)
}
} else {
right = rightStack[len(rightStack) - 1]
rightStack = rightStack[:len(rightStack) - 1]
for node := right.Left; node != nil ; node = node.Right {
rightStack = append(rightStack, node)
}
}
}
return false
}