LeetCode the binary search tree into a tree cumulative

The first 538 title


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

例如:

输入: 二叉搜索树:
              5
            /   \
           2     13

输出: 转换为累加树:
             18
            /   \
          20     13

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-bst-to-greater-tree

concept

Binary search tree

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

Preorder

中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。

Problem-solving ideas

  • By definition we know that, in order to traverse a BST increasing sequence
  • We will preorder inverted (first left sub-tree, the root node, then the right subtree), you can achieve a descending sequence
  • The traversal sequence, and to update the accumulated small node values ​​from a large, accumulated to achieve tree (original node = node value plus all values ​​greater than the sum of its node value)

Code

1. The idea of ​​the recursive traversal sequence inverted achieved

//递归实现
class Solution1 {
    public TreeNode convertBST(TreeNode root) {
        addSum(root, 0);
        return root;
    }

    public int addSum(TreeNode node, int parentVal) {
        //如果没有节点了,返回父节点值
        if (node == null) {
            return parentVal;
        }

        //累加右边所有节点值
        int rVal = addSum(node.right, parentVal);

        //当前节点值=右边所有节点累加值+当前节点值
        node.val += rVal;
        //System.out.println("当前节点值:" + node.val);

        //累加左边所有节点值
        int lVal = addSum(node.left, node.val);
        return lVal;
    }
}

2. Use the stack, to recursive Implementation

//利用堆栈,去递归化
class Solution2 {
    public TreeNode convertBST(TreeNode root) {
        TreeNode oRoot = root;
        Stack<TreeNode> stack = new Stack();
        int sum = 0;
        while (true) {
            //右节点入栈
            while (root != null) {
                stack.push(root);
                root = root.right;
            }

            //如果栈为空退出循环
            if (stack.empty()) {
                break;
            }
            //否则出栈进入计算
            else {
                TreeNode node = stack.pop();
                //更新节点值
                node.val += sum;
                //更新sum值
                sum = node.val;
                //左节点进入[右节点入栈]
                root = node.left;
            }
        }
        //返回原树,此时该树所有节点已做更新
        return oRoot;
    }
}

to sum up

We achieve by submitting the code found in the stack will be much slower than the recursive execution efficiency, because:

  • Jvm tail recursion is optimized compiler recognizes treated and for which the corresponding iteration
  • Stack implementation requires frequent push (stack), pop (pop) operation causes performance degradation

data

Guess you like

Origin www.cnblogs.com/tqlin/p/11565256.html