当前位置: 首页 > 科技观察

让我们来谈谈一种叫做累积树的树!

时间:2023-03-20 15:05:45 科技观察

将二叉搜索树转换为累积树。题目:https://leetcode-cn.com/problems/convert-bst-to-greater-tree/给定一棵二叉搜索树的根节点,该树的节点值不同,请将其转化为GreaterSumTree,使得每个node节点的新值等于原树中大于等于node.val的值之和。提醒一下,二叉搜索树满足以下约束:节点的左子树仅包含键小于节点键的节点。节点的右子树仅包含键大于节点键的节点。左右子树也必须是二叉搜索树。示例1:将二叉搜索树转换为累积树输入:[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]示例2:输入:root=[0,null,1]输出:[1,null,1]示例3:输入:root=[1,0,2]输出:[3,3,2]示例4:输入:root=[3,2,4,1]输出:[7,9,4,10]提示:树的节点数在0到104之间,每个节点的值在-104到104之间,树中的所有值都是互不相同的。给定的树是二叉搜索树。思路一看到积累树,相信很多朋友都会疑惑:如何积累?遇到一个节点,再遍历其他节点累加?想想怎么就这么麻烦。然后发现这是一棵二叉查找树,二叉查找树,这是有顺序的。那么如果有序元素累加了呢?事实上,这是一棵树,您可能觉得它有点笨拙。从另一个角度来看,这是一个有序数组[2,5,13]。累加数组,也就是[20,18,13],是不是感觉这个很简单。为什么转成数组感觉简单?因为大家都知道怎么遍历数组,从后往前,一个一个加起来。这个换成了二叉搜索树,看起来很别扭是不是?那么知道怎么遍历这个二叉树就很容易解决了。从树上可以看出,累加的顺序是右中左,所以我们需要倒序遍历这棵二叉树,然后依次累加。递归遍历的顺序如图:将二叉搜索树转化为累积树这道题还是需要一个前置指针来记录当前遍历的节点cur的前一个节点,这样方便累积。前置指针的使用技巧,我们在二叉树:搜索树和二叉树的最小绝对差:我的模式是什么?综上所述,这是一种常用的操作手段。递归函数的参数和返回值在这里就很清楚了。不需要对递归函数的返回值做任何处理,需要遍历整棵树。同时需要定义一个全局变量pre,用来保存cur节点的前一个节点的值,可以定义为int类型。代码如下:intpre;//记录上一个节点的值voidtraversal(TreeNode*cur)判断终止条件,为空则终止。如果(cur==NULL)返回;确定单级递归的逻辑。注意二叉树必须从右向左遍历。中间节点的处理逻辑是将cur的值加到前一个节点的值上。代码如下:traversal(cur->right);//rightcur->val+=pre;//middlepre=cur->val;traversal(cur->left);//left的整体代码递归方法如下:classSolution{private:intpre;//记录上一个节点的值voidtraversal(TreeNode*cur){//右中左遍历if(cur==NULL)return;traversal(cur->right);cur->val+=pre;pre=cur->val;traversal(cur->left);}public:TreeNode*convertBST(TreeNode*root){pre=0;traversal(root);returnroot;}};Iterativemethod迭代法其实就是一个inordertemplate题没错,在二叉树:前中序迭代法和二叉树:前中序统一法迭代法中,可以选择自己习惯的一种写法。这里我给出其中一个,代码如下:classSolution{private:intpre;//记录上一个节点的值voidtraversal(TreeNode*root){stackst;TreeNode*cur=root;while(cur!=NULL||!st.empty()){if(cur!=NULL){st.push(cur);cur=cur->right;//right}else{cur=st.top();//中间st.pop();cur->val+=pre;pre=cur->val;cur=cur->left;//left}}}public:TreeNode*convertBST(TreeNode*root){pre=0;遍历(root);returnroot;}};总结经历了各种二叉树的增删改查的洗礼,这道题应该比较简单了。好了,二叉树就告一段落了,接下来就是对二叉树做一个大总结了。其他语言版本JavaclassSolution{intsum;publicTreeNodeconvertBST(TreeNoderoot){sum=0;convertBST1(root);returnroot;}//按右中左顺序遍历累加publicvoidconvertBST1(TreeNoderoot){if(root==null){return;}convertBST1(root.right);sum+=root.val;root.val=sum;convertBST1(root.left);}}Python递归方法classSolution:defconvertBST(self,root:TreeNode)->TreeNode:defbuildalist(root):ifnotroot:returnNonebuildalist(root.right)#右中左遍历root.val+=self.preself.pre=root.valbuildalist(root.left)self.pre=0#记录上一个节点buildalist(root)的值)returnroot本文转载自微信公众号《代码随想录》,可通过以下二维码关注。转载本文请联系CodeCaprice公众号。