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

80 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

题目描述

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。

例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。 对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。

返回这些数字之和。题目数据保证答案是一个 32 位 整数。

示例

image.png

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

提示

  • 树中的节点数在 [1, 1000] 范围内
  • Node.val 仅为 0 或 1

后序遍历

通过后序遍历,我们可以按序得到得到其左节点,右节点,当前节点,节点元素通过层级左移得到实际对应的值,再将其结果相加,记得得出跟节点到叶子节点路径所表示的数字。

class Solution {
    public int sumRootToLeaf(TreeNode root) {
        return dfs(root, 0);
    }

    public int dfs(TreeNode root, int val) {
        if (root == null) {
            return 0;
        }
        
        // 向左位移,得到当前节点实际的值
        val = (val << 1) | root.val;
        // 如果该节点为叶子节点,则返回结果
        if (root.left == null && root.right == null) {
            return val;
        }
        
        // 否则返回子节点之和
        return dfs(root.left, val) + dfs(root.right, val);
    }
}

迭代

class Solution {
    public int sumRootToLeaf(TreeNode root) {
        Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
        int val = 0, ret = 0;
        TreeNode prev = null;
        // 遍历所有的节点
        while (root != null || !stack.isEmpty()) {
            // 先获取左节点
            while (root != null) {
                val = (val << 1) | root.val;
                stack.push(root);
                root = root.left;
            }
            root = stack.peek();
            // 再获取右边节点
            if (root.right == null || root.right == prev) {
                if (root.left == null && root.right == null) {
                    ret += val;
                }
                val >>= 1;
                stack.pop();
                prev = root;
                root = null;
            } else {
                root = root.right;
            }
        }
        return ret;
    }
}