【樹】B040_LC_從根到葉的二進制數之和(回溯 / 遞歸)

一、Problem

給出一棵二叉樹,其上每個結點的值都是 0 或 1 。每一條從根到葉的路徑都代表一個從最高有效位開始的二進制數。例如,如果路徑爲 0 -> 1 -> 1 -> 0 -> 1,那麼它表示二進制數 01101,也就是 13 。

對樹上的每一片葉子,我們都要找出從根到該葉子的路徑所表示的數字。

以 10^9 + 7 爲模,返回這些數字之和。
在這裏插入圖片描述

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

提示:

樹中的結點數介於 1 和 1000 之間。
node.val 爲 0 或 1 。

二、Solution

方法一:回溯

思路

到達葉子結點的時候結算即可,結算完畢需要將該葉子結點的值的貢獻抹掉;而且當以某一個結點 node 爲根的子樹遍歷完成後,該 node 的貢獻也抹掉

class Solution {
    int sum, x, rVal;
    void dfs(TreeNode root) {
        if (root.left == null && root.right == null) {
            x = (x << 1) | root.val;
            sum += x;
            x = x >>> 1;
            return;
        }
        x = (x << 1) + root.val;
        if (root.left != null)  dfs(root.left);
        if (root.right != null) dfs(root.right);
        x = x >>> 1;
    }
    public int sumRootToLeaf(TreeNode root) {
        rVal = root.val;
        dfs(root);
        return sum;
    }
}

x = (x << 1) + root.val,這句話可以改爲 x = (x << 1) | root.val,因爲 root.val 爲 0/1

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(1)O(1)

上面的方法我們是自己寫邏輯進行回溯,然兒沒有利用遞歸的自帶回溯,如果用了的話,代碼會更簡潔,但我覺得上面的代碼比較易懂…

class Solution {
    int dfs(TreeNode root, int x) {
        if (root == null)
            return 0;
        x = (x << 1) | root.val;
        if (root.left == null && root.right == null)
            return x;
        return dfs(root.left, x) + dfs(root.right, x);
    }
    public int sumRootToLeaf(TreeNode root) {
        return dfs(root, 0);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章