每日算法----把二叉搜索树转换为累加树----2020/09/21

1 题目描述

给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。

2 实例

在这里插入图片描述

3 思路
  • 先实现根节点的累加,遍历所有节点。
  • 在实现左右子节点的累加遍历
4 遇上的问题
  • 遍历?先序后序中序,要哪个遍历好,最后选择了中序。
  • 题目累加的要求大于等于原节点值,那就要比较,如果要比较那就要传值。(做完看官方题解才发现,原来给的二叉树是排好序的!!!)所以又重载了原方法,导致 代码量又加大了。真是莫得常识的笨猫。
  • 累加的树,emm,但是第一次改的时候发现,我遍历第一个节点值,累加完发现树被修改了,对后面的遍历产生了影响!我又建了一个新树(笨猫)
5 结果

在这里插入图片描述

6 反思
  • 二叉搜索树,是一个左节点小于父节点,右节点大于父节点的树!
  • 时间耗费太多了,全部遍历太浪费了,毕竟左右节点已经大小区分好了。可以只遍历右节点和父节点的,然后累加起来。
  • 思维不够清晰,需要再狂练啊!
  • 又是可读性极差,长得像裹脚布的又不好读。需要再注意!
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
	//全局变量copyTree,用于保存累加后的值。
	TreeNode copyTree ;
	//给定的方法结构,后来被我重载了
    public TreeNode convertBST(TreeNode root) {
    	//如果null对象进来就直接返回
        if(root == null){
            return null;
        }
        //给copyTree创建和给定的树值一样的父节点
        copyTree = new TreeNode(root.val);
        //把给的树和copyTree树传过去给重载方法
        convertBST(root,root,copyTree);
        return copyTree;
    }
	//中序遍历,每次从头开始
public void convertBST(TreeNode node,TreeNode root,TreeNode copyTree) {
	//遍历值和创建对应累加树节点的方法
     equalsVal(root,node.val,copyTree);
	//对左节点进行递归遍历
     if(node.left!=null){
         copyTree.left = new TreeNode(node.left.val);
         convertBST(node.left,root,copyTree.left);
     }
	//对右节点进行递归遍历
     if(node.right!=null){
         copyTree.right = new TreeNode(node.right.val);
         convertBST(node.right,root,copyTree.right);
     }
}
//遍历值和创建对应累加树节点的方法
//root 根节点,每次遍历的开头
//target 目标节点的值,要和其他节点比较大小的节点的节点值
//copyTree 用于保存累加树节点
public int equalsVal(TreeNode root,int target,TreeNode copyTree){
	   int value = 0;
	   //节点存在,节点值大于目标节点,并且累加过程中要包含自己的值
	   if(root!=null&& root.val >= target){
	       value += root.val;
	   }
		//左子树不为空,左子树进行递归
	   if(root.left != null){
	       value += equalsVal(root.left,target,copyTree);
	   }
		//右子树不为空,右子树进行递归
	   if(root.right != null){
	       value += equalsVal(root.right,target,copyTree);
	   }
		//将值赋给了copyTree
	   copyTree.val = value;
		//在比较过程中,如果对该节点的值比目标节点大的话,返回比较的结果
	   if(root.val >= target){
	       return value;
	   }else{
	       return value;
	   }
    }
}
7 学习官方的算法
class Solution {
    int sum = 0;

    public TreeNode convertBST(TreeNode root) {
        if (root != null) {
            convertBST(root.right);
            sum += root.val;
            root.val = sum;
            convertBST(root.left);
        }
        return root;
    }
}
/*
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/convert-bst-to-greater-tree/solution/ba-er-cha-sou-suo-shu-zhuan-huan-wei-lei-jia-sh-14/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/

在这个算法里,巧妙的运用了二叉搜索树左子树必然小于根节点,右子树必然大于根节点,树的最深最右节点开始累加,遍历右、中、左,并且累加赋值,只需要遍历一遍树,一边遍历一边赋值,也就是O(n),就可以直接得到一颗累加树。

但是也存在问题,这个算法里默认没有相同值,如果有相同的两个数,就会出现问题,因为在累加中并不存在判断,所以一旦有相同的值也照样会累加,但是题目要求的是自身和大于自身的所有值,所以会出现问题。

我搜了搜BST,发现BST是二叉搜索树,在这个二叉搜索树中结构里用次数表示相同的数,有相同则index加1,然而官方在注释中给的树结构并没有一个int类型的index应该是默认不考虑相等情况。

8 收获
  • BST,二叉搜索树(二次排序树、二次查找树),根节点必定大于左子树,必定小于右子树,左子树和右子树也依然是二次搜索树。
  • 写算法时利用树的特性会使得算法设计更为简单!。

题目来源:力扣(LeetCode)
相关链接
题目著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值