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:
- The hundreds digit represents the depth
D
of this node,1 <= D <= 4.
- 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. - 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; } };
類似題目:
參考資料:
https://discuss.leetcode.com/topic/101111/java-solution-represent-tree-using-hashmap