LeetCode437. Path Sum III

版权声明:本文为博主原创文章,欢迎转载!转载请保留原博客地址。 https://blog.csdn.net/grllery/article/details/85254963

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://blog.csdn.net/grllery/article/details/85253178类似。不同的地方在于pathSum中计算的方式。因为二叉树的特性,因此将根结点改为左右结点,分别调用pathSum函数,从而更改了helper函数的中的搜索起点,类似于暴力搜索。

代码见: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;
	}
};

猜你喜欢

转载自blog.csdn.net/grllery/article/details/85254963
今日推荐