lc0331

✅ 538. 把二叉搜索树转换为累加树

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

描述

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

 

例如:

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

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

注意:本题和 1038: https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/ 相同

解答

我们要遍历整个二叉树,然后找比较大的吗?

非也,二叉搜索树 BST 有性质:右边的大啊。

RNL的 中序遍历搞一搞。

java

以右->根->左的顺序遍历二叉树,将遍历顺序的前一个结点的累加值记录起来,和当前结点相加,得到当前结点的累加值。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int preNum = 0;
    //递归写法
    public TreeNode convertBST(TreeNode root) {
        unPreOrder(root);
        return root;        
    }
     public void unPreOrder(TreeNode root){
        if(root == null)
            return;
        unPreOrder(root.right);
        root.val += preNum;
        preNum = root.val;
        unPreOrder(root.left);
    }
    //非递归写法 todo 重点观看 
    /*public TreeNode convertBST(TreeNode root) {
        if(root == null)
            return root;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        //stack.add(root);
        TreeNode node = root;
        while(node != null || !stack.isEmpty()){
            while(node != null){
                stack.add(node);
                node = node.right;
            }
            node = stack.pop();
            node.val += preNum;
            preNum = node.val;
            if(node.left != null)
                node = node.left;
            else
                node = null;
        }
        return root;
    }*/    
}

py

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    my_sum = 0
    def convertBST(self, root: TreeNode) -> TreeNode:
        if root is None: 
            return

        self.convertBST(root.right)
        tmp = root.val
        root.val += self.my_sum
        self.my_sum += tmp
        self.convertBST(root.left)

        return root
'''
执行用时 :
132 ms
, 在所有 Python3 提交中击败了
16.13%
的用户
内存消耗 :
15.9 MB
, 在所有 Python3 提交中击败了
5.44%
的用户
'''

✅ 1022. 从根到叶的二进制数之和

https://leetcode-cn.com/problems/sum-of-root-to-leaf-binary-numbers/

描述

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。

对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。

以 10^9 + 7 为模,返回这些数字之和。(tt: aka: 即下面java 里的 1000_000_007 )

 

示例:


image.png

输入:[1,0,1,0,1,0,1]
输出:22
解释:(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22

解答

还是遍历问题。DFS 到头了,然后就进行转10进制呗。(c在过程中就边走边计算,不是最后才转10进制)

c

//C 语言描述。
//tt 由此,你可以深刻理解 递归 的实质。

int _sumRootToLeaf(struct TreeNode *root, int num) {
    int sum = 0; 
    //计算 加上 这个节点后的 总值num
    num = (num << 1) + root->val;
    // 如果已经到了尽头,那么就返回这个 总值num
    if (root->left == NULL && root->right == NULL) return num;
    // 如果还没到 左边 的尽头,那么就把 左边 孩子的总值, 算出来,记得传当前
    // 的总值 num 进去。 
    if (root->left) sum += _sumRootToLeaf(root->left, num);
    // 如果还没到 右边 的尽头,那么就把 右边 孩子的总值, 算出来,记得传当前
    // 的总值 num 进去。
    if (root->right) sum += _sumRootToLeaf(root->right, num);
    return sum; 
}

int sumRootToLeaf(struct TreeNode *root) {
    return root ? _sumRootToLeaf(root, 0) : 0;
}

java

class Solution {
    public int sumRootToLeaf(TreeNode root) {
            if (root == null) return 0;
        int mod = root.val % 1000_000_007;
        if (root.left == null && root.right == null) return mod;
        if (root.left != null) root.left.val += mod << 1;
        if (root.right != null) root.right.val += mod << 1;
        //tt 这种方式 似乎 就像是 ,把每个 父亲 节点的值,依次下放
        // 到每个子节点,然后最后这句,下面这句 return ,就是
        // 递归处理每个子节点。
        return (sumRootToLeaf(root.left) + sumRootToLeaf(root.right)) % 1000_000_007;
    }
}
//牛,实在是牛

class Solution {
    int sum =0;
    int num = 0;
    public int sumRootToLeaf(TreeNode root) {
    //从根节点开始,记录二进制
        if (root==null)return 0;
        num = (num<<1) + root.val;//tt1 这样就做到了边走 边转位 10进制
        if (root.left==null&&root.right==null){//如果是叶子节点
            sum += num;
        }
        sumRootToLeaf(root.left);
        sumRootToLeaf(root.right);
        num = (num-root.val)>>1;//tt 这里算是回溯,是tt1 的正好的逆操作
        //tt 其实这个回溯 还是 需要 下一次理解 ,todo 
        return sum;
    }
}

py

只是重写了上面的c

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sumRootToLeaf(self, root: TreeNode) -> int:
        def _sumRootToLeft(root: TreeNode, num: int):
            num = (num << 1) + root.val
            if (root.left is None) and (root.right is None):
                return num
            # if not go to the end
            sum = 0
            if (root.left is not None):
                sum += _sumRootToLeft(root.left, num)
            if (root.right is not None):
                sum += _sumRootToLeft(root.right, num)
            return sum
        if root is None:
            return 0
        else:
            return _sumRootToLeft(root, 0)
'''
执行用时 :
84 ms
, 在所有 Python3 提交中击败了
5.37%
的用户
内存消耗 :
14.1 MB
, 在所有 Python3 提交中击败了
5.41%
的用户
'''

posted on 2020-03-31 17:01  Paulkg12  阅读(152)  评论(0)    收藏  举报

导航