LeetCode437. Path Sum III
437. Path Sum III
You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
計算二叉樹中從上到下的路徑中和為目標值的個數。路徑的起點可以是子樹的根結點,終點可以不是葉子結點,但一定是自上而下的。
helper函式用於計算從root到各個葉子結點路徑上和為目標值的個數,這個和
程式碼見:https://github.com/abesft/leetcode/blob/master/437PathSumIII/437PathSumIII.cpp
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; //https://leetcode.com/problems/path-sum-iii/discuss/91889/Simple-Java-DFS class Solution { public: int pathSum(TreeNode* root, int sum) { if (root == nullptr) return 0; int ans = 0; helper(root, ans, sum); return ans + pathSum(root->left, sum) + pathSum(root->right, sum); } private: void helper(TreeNode* root, int &ans, int remain) { if (root == nullptr) return; remain -= root->val; if (remain == 0) ans++; helper(root->left, ans, remain); helper(root->right, ans, remain); } };
第二種方法是用hash表記錄前面已經出現過的和以及次數,然後查詢hash表中是否存在 current_sum - target_sum 這個鍵值。具體分析見https://blog.csdn.net/grllery/article/details/85332237。
#include <iostream>
#include<unordered_map>
using namespace std;
//https://leetcode.com/problems/path-sum-iii/discuss/91878/17-ms-O(n)-java-Prefix-sum-method
class Solution2 {
public:
int pathSum(TreeNode* root, int sum) {
int res = 0;
//key:前i個元素的和,value:對應和的個數
unordered_map<int, int> sum_counts;
int current_sum = 0;
sum_counts[current_sum]++;
preSum(root, sum_counts, current_sum, sum, res);
return res;
}
private:
void preSum(TreeNode* root, unordered_map<int, int>& sum_counts, int& current_sum, int& target_sum, int& res) {
if (root == nullptr)
return;
current_sum += root->val;
auto iter = sum_counts.find(current_sum - target_sum);
if (iter != sum_counts.end())
res += iter->second;
sum_counts[current_sum]++;
preSum(root->left, sum_counts, current_sum, target_sum, res);
preSum(root->right, sum_counts, current_sum, target_sum, res);
sum_counts[current_sum]--;
current_sum -= root->val;
}
};