题目
题目来源:力扣(LeetCode)
给定一个二叉搜索树 root 和一个目标结果 k,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
示例 1:
输入: root = [5,3,6,2,4,null,7], k = 9
输出: true
示例 2:
输入: root = [5,3,6,2,4,null,7], k = 28
输出: false
示例 3:
输入: root = [2,1,3], k = 4
输出: true
示例 4:
输入: root = [2,1,3], k = 1
输出: false
示例 5:
输入: root = [2,1,3], k = 3
输出: true
思路分析
中序遍历 + 双指针
二叉搜索树的中序遍历结果是一个升序序列,我们定义两个指针 left 和 right 分别指向升序序列的头部索引和尾部索引,然后执行以下操作:
检查 left 和 right 索引处两元素之和是否等于 k。如果等于,则返回 True。
如果当前两元素之和小于 k,则更新 left 指向下一个元素。这是因为当我们需要增大两数之和时,应该增大较小数。
如果当前两元素之和大于 k,则更新 right 指向上一个元素。这是因为当我们需要减小两数之和时,应该减小较大数。
重复步骤一至三,直到左指针 left 大于右指针 right。
如果左指针 left到右指针 right 的右边,则返回 False。
/*** Definition for a binary tree node.* function TreeNode(val, left, right) {* this.val = (val===undefined ? 0 : val)* this.left = (left===undefined ? null : left)* this.right = (right===undefined ? null : right)* }*//*** @param {TreeNode} root* @param {number} k* @return {boolean}*/var inorder = function (root, ret) {if (root == null) return;inorder(root.left, ret);// ret数组中依次按着从小到大的顺序,存储二叉树的节点值ret.push(root.val);inorder(root.right, ret);return;};var findTarget = function (root, k) {let ret = [];// 中序遍历二叉搜索树inorder(root, ret);// 设置头指针left指向升序序列头部索引let left = 0;// 设置尾指针 right 指向升序序列尾部索引let right = ret.length - 1;//while (left < right && ret[left] + ret[right] - k) {// left 和 right 索引处两元素之和如果小于k,头指针往后走,否则,尾指针往前走if (ret[left] + ret[right] < k) left += 1;else right -= 1;}// 如果left还是小于right,证明这个时候二叉排序树中存在两个值相加等于kreturn left < right;};
广度优先搜索 + Set集合
我们定义一个 Set 集合存储遍历过的节点。使用广度优先搜索遍历二叉搜索树,首先将根节点加入 queue 中,然后执行以下步骤:
- 从队列首部删除一个元素 p 。
- 检查 setset 中是否存在 k - p。如果存在,返回 True。
- 否则,将 pp 加入 set 。然后将当前节点的左孩子和右孩子加入 queue
- 重复步骤一至三,直到 queue 为空。
- 如果 queue 为空,返回 False。
/*** Definition for a binary tree node.* function TreeNode(val, left, right) {* this.val = (val===undefined ? 0 : val)* this.left = (left===undefined ? null : left)* this.right = (right===undefined ? null : right)* }*//*** @param {TreeNode} root* @param {number} k* @return {boolean}*/var findTarget = function (root, k) {const set = new Set();const queue = [];if (!root) return falsequeue.push(root)while (queue.length) {const node = queue.pop();if (set.has(k - node.val)) {return true}set.add(node.val)node.left != null && queue.push(node.left)node.right != null && queue.push(node.right)}return false};
