前端刷题路-Day41: 二叉搜索树的范围和(题号938)

157 阅读2分钟

这是我参与更文挑战的第5天,活动详情查看: 更文挑战

二叉搜索树的范围和(题号938)

题目

给定二叉搜索树的根结点 root,返回值位于范围[low, high]之间的所有结点的值的和。

示例 1:

img

输入:root = [10,5,15,3,7,null,18], low = 7, high = 15
输出:32

示例 2:

img

输入:root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10
输出:23

提示:

  • 树中节点数目在范围 [1, 2 * 104]
  • 1 <= Node.val <= 105
  • 1 <= low <= high <= 105
  • 所有 Node.val 互不相同

链接

leetcode-cn.com/problems/ra…

解释

这题啊,这题其实就是剪枝,只要把剪枝条件写好了,剩下的其实非常简单。

首先看题目,这是一个二叉搜索树,那么就不用找到所有节点了。一个节点左子树的值必然比当前节点的值小,右子树的值必然比当前节点的值大。

这样剪枝条件就很明显了,如果当前节点的值小于最小值,那么其左子树的值就不用考虑了;同理可得如果当前节点的值比最大值大,那么其右子树的值就不用考虑了。

就是这么简单,那么接下来看看递归和迭代两种写法。

自己的答案(迭代)

var rangeSumBST = function(root, low, high) {
  var res = 0
      stack = [root]
  while (stack.length) {
    root = stack.pop()
    if (root.val < low) {
      root.right && stack.push(root.right)
      continue
    }
    if (root.val > high) {
      root.left && stack.push(root.left)
      continue
    }
    root.left && stack.push(root.left)
    root.right && stack.push(root.right)
    res += root.val
  }
  return res
};

非常简单,如果当前节点的值小于最小值,那么只将其右子树推入到栈中,并且结束此次迭代;同理可以得到大于最大值时的处理方式。如果没有走到两个if中去,那就证明这个节点的值在最大值和最小值中间,将左右子树都推入栈并且累计res即可。

自己的答案(递归)

递归也是很简单,这里为了方便就不新建一个递归函数了,直接调用原函数。

var rangeSumBST = function(root, low, high) {
  if (!root) return 0
  if (root.val < low) return rangeSumBST(root.right, low, high)
  if (root.val > high) return rangeSumBST(root.left, low, high)
  return root.val + rangeSumBST(root.left, low, high) + rangeSumBST(root.right, low, high)
};

首先是递归的终止条件,当节点为null时结束递归,因为此时已经递归到头了。

之后如果当前节点值小于最小值,返回右子树的递归结果,如果当前节点大于最大值,返回左子树的递归结果。

如果当前节点在最大值和最小值之间,那么就返回左右递归结果的和加上当前节点值。

相比迭代来说,递归的代码好像更简单一些,不过知道两种解法总比一种好些。

更好的答案



PS:想查看往期文章和题目可以点击下面的链接:

这里是按照日期分类的👇

前端刷题路-目录(日期分类)

经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇

前端刷题路-目录(题型分类)

有兴趣的也可以看看我的个人主页👇

Here is RZ