[LeetCode] Path Sum IV 二叉樹的路徑和之四


 

If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digits integers.

For each integer in this list:

  1. The hundreds digit represents the depth D of this node, 1 <= D <= 4.
  2. The tens digit represents the position P of this node in the level it belongs to, 1 <= P <= 8. The position is the same as that in a full binary tree.
  3. The units digit represents the value V of this node, 0 <= V <= 9.

 

Given a list of ascending three-digits integers representing a binary with the depth smaller than 5. You need to return the sum of all paths from the root towards the leaves.

Example 1:

Input: [113, 215, 221]
Output: 12
Explanation: 
The tree that the list represents is:
    3
   / \
  5   1

The path sum is (3 + 5) + (3 + 1) = 12.

 

Example 2:

Input: [113, 221]
Output: 4
Explanation: 
The tree that the list represents is: 
    3
     \
      1

The path sum is (3 + 1) = 4.

 

這道題還是讓我們求二叉樹的路徑之和,但是跟之前不同的是,樹的存儲方式比較特別,並沒有專門的數結點,而是使用一個三位數字來存的,百位數是該結點的深度,十位上是該結點在某一層中的位置,個位數是該結點的結點值。為了求路徑之和,我們肯定還是需要遍歷樹,但是由於沒有樹結點,所以我們可以用其他的數據結構代替。比如我們可以將每個結點的位置信息和結點值分離開,然后建立兩者之間的映射。比如我們可以將百位數和十位數當作key,將個位數當作value,建立映射。由於題目中說了數組是有序的,所以首元素就是根結點,然后我們進行先序遍歷即可。在遞歸函數中,我們先將深度和位置拆分出來,然后算出左右子結點的深度和位置的兩位數,我們還要維護一個變量cur,用來保存當前路徑之和。如果當前結點的左右子結點不存在,說明此時cur已經是一條完整的路徑之和了,加到結果res中,直接返回。否則就是對存在的左右子結點調用遞歸函數即可,參見代碼如下:

 

解法一:

class Solution {
public:
    int pathSum(vector<int>& nums) {
        if (nums.empty()) return 0;
        int res = 0;
        unordered_map<int, int> m;
        for (int num : nums) {
            m[num / 10] = num % 10;
        }
        helper(nums[0] / 10, m, 0, res);
        return res;
    }
    void helper(int num, unordered_map<int, int>& m, int cur, int& res) {
        int level = num / 10, pos = num % 10;
        int left = (level + 1) * 10 + 2 * pos - 1, right = left + 1;
        cur += m[num];
        if (!m.count(left) && !m.count(right)) {
            res += cur;
            return;
        }
        if (m.count(left)) helper(left, m, cur, res);
        if (m.count(right)) helper(right, m, cur, res);
    }
};

 

下面這種方法是迭代的形式,我們使用的層序遍歷,與先序遍歷不同的是,我們不能維護一個當前路徑之和的變量,這樣會重復計算結點值,而是在遍歷每一層的結點時,加上其父結點的值,如果某一個結點沒有子結點了,才將累加起來的結點值加到結果res中,參見代碼如下:

 

解法二:

class Solution {
public:
    int pathSum(vector<int>& nums) {
        if (nums.empty()) return 0;
        int res = 0, cur = 0;
        unordered_map<int, int> m;
        queue<int> q{{nums[0] / 10}};
        for (int num : nums) {
            m[num / 10] = num % 10;
        }
        while (!q.empty()) {
            int t = q.front(); q.pop();
            int level = t / 10, pos = t % 10;
            int left = (level + 1) * 10 + 2 * pos - 1, right = left + 1;
            if (!m.count(left) && !m.count(right)) {
                res += m[t];
            }
            if (m.count(left)) {
                m[left] += m[t];
                q.push(left);
            }
            if (m.count(right)) {
                m[right] += m[t];
                q.push(right);
            }
        }
        return res;
    }
};

 

類似題目:

Path Sum III

Binary Tree Maximum Path Sum

Path Sum II

Path Sum

 

參考資料:

https://discuss.leetcode.com/topic/101111/java-solution-represent-tree-using-hashmap

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM