leetcode hot100之把二叉搜索树转换为累加树(538)解析

149 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情


前言

  • leetcode hot100,是大厂面试高频题,也是必刷算法题。精选了100道LeetCode上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,按照官方说的,熟练掌握这 100 道题,就具备了代码世界通行的基本能力。

leetcode538题(把二叉搜索树转换为累加树

本文来讲hot100第538题,把二叉搜索树转换为累加树,本题题目是中等题目,是比较典型的二叉搜索树的反中序遍历的应用。

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

注意: 本题和 1038: leetcode-cn.com/problems/bi… 相同 示例:

输入: [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出: [30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
输入: root = [0,null,1]
输出: [1,null,1]
输入: root = [1,0,2]
输出: [3,3,2]
输入: root = [3,2,4,1]
输出: [7,9,4,10]

分析

我们得到几个信息点

  1. 二叉搜索树 若它的左子树不为空,则所有左子树上的值均小于其根节点的值 若它的右子树不为空,则所有右子树上的值均大于其根节点得值 它的左右子树也分别为二叉搜索树
  2. 累加树: 每个节点node的新值等于原树中大于或等于 node.val 的值之和, 其实就是求树中大于等于该节点值的所有节点的总和。

思路

  • 最后一个节点是8,那么树中最大的值是8,所以累加和是8;倒数第二个是7,树中全部大于等于7的,只有7和8,所以累加和是15,以此类推
  • 因为是二叉搜索树,右侧存在的话是比左侧大的,那么最大的值一定是树的最下面一层的右侧的值
  • 所以我们可以从下向上,从右向左遍历
  • 遍历方向应该是右中左,这种也叫反中序遍历,

代码

递归,深度搜索优先,借助累加值,右中左迭代:

  const dfs = (node, add = 0) => {
    if (!node) return node
    // 记录下
    let res = add;
    if (node.right !== null) {
      // 对于右侧节点,其累加值是在父节点的父节点上基础进行的, 所以有res存在;
      res = dfs(node.right, res);
    }
    // 右侧节点有值,我们就把返回的值拿来给当前节点增加
    node.val += res
    // 更新累加值
    res = node.val
    // 左侧节点是基于当前节点累加的,累加后,左侧的值肯定就是最大的
    if (node.left !== null) {
      res = dfs(node.left, res)
    }
    // 返回上一层
    return res
  }
  dfs(root)
  return root

方式二:迭代法

  • 逆向中序遍历,左中右->右中左
  • 节点的值等于它自己加上它的前一个节点的值【逆向】
if(!root) return null;
let stack = [];
let node = root;
let prenode = null;
while(node || stack.length) {
    while(node) {
        stack.push(node)
        node = node.right;
    }
    node = stack.pop();
    if(prenode) {
        node.val += prenode.val;
    }
    prenode = node;
    node = node.left;
}
return root;

结语

  • 本题递归和迭代都可以解决,需要有一些处理二叉树的基础,还要知道二叉搜索树的规则,此题比较困难的是对题目的理解,只要知道题目意思是求树中大于等于该节点值的所有节点的总和,就没什么问题了。