63、★LeetCode-538.把BST转换为累加树

题目描述

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

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

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

来源:力扣(LeetCode)

思路

自己的想法:

①先从最右开始累加,设置一个类成员变量,记录每次最终要改变的值!

返回上一层:需要使用栈来记录上一层节点;还要使用一个标志,防止返回上一层后重复往右查找陷入死循环

优化:cur != null 作为判定,将每一个节点都加入,while(root != null || !stack.isEmpty())作为判定,实际将树中的所有节点都入栈了一遍,是常规的迭代实现方式!

答案思路

①递归:实现简单!

其实递归实现中,根节点root可以认为是某次递归中的 左或者右节点!

实际就是往左走、往右走和处理当前节点的逻辑,三个部分顺序来实现前中后的逻辑!

代码

1)自己手写实现的 繁琐的迭代实现过程

class Solution {
    //树的结构不变,只是将节点的值改变
    private int num = 0;//用来作为被修改的值
    public TreeNode convertBST(TreeNode root) {
        //一直走到右,从右边开始
        if(root == null) return root;
        TreeNode cur = root;
        boolean flag = false;
        //用栈吧,实现返回上一层的逻辑
        Stack stack = new Stack<>();
        while(cur != null){
            while(cur.right != null && flag == false){
                stack.push(cur);
                cur = cur.right;
            }
            //此时cur是最右边的值
            num += cur.val; //累加num
            cur.val = num;//改变该点的值
            //不为空,往左走
            if(cur.left != null){
                cur = cur.left;
                flag = false;
            }
            //空了,就返回上一层
            else if(cur.left == null && !stack.isEmpty()){
                cur = stack.pop();//会死循环
                flag = true;
            }else{
                break;
            }
        }
        return root;
    }
}

优化:常规的迭代逻辑实现,每次都将节点加入,将是否为null作为结束条件!

耗时更多了

class Solution {
    private int num = 0;
    public TreeNode convertBST(TreeNode root) {

        if(root == null) return root;
        TreeNode cur = root;
        Stack stack = new Stack<>();
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.right;
            }
            //处理 中间根节点的逻辑
            cur = stack.pop();
            num += cur.val; //累加num
            cur.val = num;//改变该点的值
    
            //向左
            cur = cur.left;//是否为null不确定
        }
        return root;
    }
}

2)递归

class Solution {
    private int num = 0;
    public TreeNode convertBST(TreeNode root) {
        if(root == null) return root;
        //如果没走到底
        root.right = convertBST(root.right);//先走右
        
        //实际的逻辑处理
        num += root.val;
        root.val = num;

        //再走左
        root.left = convertBST(root.left);
        //处理完返回
        return root;
    }
}

你可能感兴趣的:(数据结构,leetcode,广度优先)