• [LeetCode] Convert BST to Greater Tree 将二叉搜索树BST转为较大树


    Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.

    Example:

    Input: The root of a Binary Search Tree like this:
                  5
                /   
               2     13
    
    Output: The root of a Greater Tree like this:
                 18
                /   
              20     13

    这道题让我们将二叉搜索树转为较大树,通过题目汇总的例子可以明白,是把每个结点值加上所有比它大的结点值总和当作新的结点值。仔细观察题目中的例子可以发现,2变成了20,而20是所有结点之和,因为2是最小结点值,要加上其他所有结点值,所以肯定就是所有结点值之和。5变成了18,是通过20减去2得来的,而13还是13,是由20减去7得来的,而7是2和5之和。我开始想的方法是先求出所有结点值之和,然后开始中序遍历数组,同时用变量sum来记录累加和,根据上面分析的规律来更新所有的数组。但是通过看论坛,发现还有更巧妙的方法,不用先求出的所有的结点值之和,而是巧妙的将中序遍历左根右的顺序逆过来,变成右根左的顺序,这样就可以反向计算累加和sum,同时更新结点值,叼的不行,参见代码如下:

    解法一:

    class Solution {
    public:
        TreeNode* convertBST(TreeNode* root) {
            int sum = 0;
            helper(root, sum);
            return root;
        }
        void helper(TreeNode*& node, int& sum) {
            if (!node) return;
            helper(node->right, sum);
            node->val += sum;
            sum = node->val;
            helper(node->left, sum);
        }
    };

    下面这种方法写的更加简洁一些,没有写其他递归函数,而是把自身写成了可以递归调用的函数,参见代码如下:

    解法二:

    class Solution {
    public:
        TreeNode* convertBST(TreeNode* root) {
            if (!root) return NULL;
            convertBST(root->right);
            root->val += sum;
            sum = root->val;
            convertBST(root->left);
            return root;
        }
    
    private:
        int sum = 0;
    };

    下面这种解法是迭代的写法,因为中序遍历有递归和迭代两种写法,逆中序遍历同样也可以写成迭代的形式,参加代码如下:

    解法三:

    class Solution {
    public:
        TreeNode* convertBST(TreeNode* root) {
            if (!root) return NULL;
            int sum = 0;
            stack<TreeNode*> st;
            TreeNode *p = root;
            while (p || !st.empty()) {
                while (p) {
                    st.push(p);
                    p = p->right;
                }
                p = st.top(); st.pop();
                p->val += sum;
                sum = p->val;
                p = p->left;
            }
            return root;
        }
    };

    参考资料:

    https://leetcode.com/problems/convert-bst-to-greater-tree/

    https://discuss.leetcode.com/topic/83455/java-recursive-o-n-time/2

    https://discuss.leetcode.com/topic/83513/one-traverse-java-solution

    https://discuss.leetcode.com/topic/83458/java-solution-7-liner-reversed-traversal

    LeetCode All in One 题目讲解汇总(持续更新中...)

  • 相关阅读:
    java内部类
    navicat使用教程-PJ
    提交代码时的注意事项
    多线程技术
    Apache POI使用详解
    网站链接收藏夹
    MySQL优化
    Oracle创建用户、角色、授权、建表
    oracle 安装提示未找到文件安装
    Json对象与Json字符串的转化、JSON字符串与Java对象的转换
  • 原文地址:https://www.cnblogs.com/grandyang/p/6591526.html
Copyright © 2020-2023  润新知