面试题 04.12. 求和路径

题目链接:leetcode.

如果只能从根节点开始

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
	vector<vector<int>> ans;
	vector<int> tmp;
	void dfs(TreeNode* root, int sum)
	{
		if(root)
		{
			sum -= root -> val;
			tmp.push_back(root -> val);
			if(root -> left)
			{
				dfs(root -> left, sum);
			}
			tmp.pop_back();
			if(root -> right)
			{
				dfs(root -> right, sum);
			}
		}
		if(sum == 0)
		{
			ans.push_back(tmp);
		}
	} 
public:
    int pathSum(TreeNode* root, int sum) {
        if(root == nullptr)
        	return 0;
        dfs(root, sum);
        return ans.size();
    }
};

为了将其扩展到从任何地方开始的路径,我们可以对所有节点暴力重复此过程。

/*
执行用时:20 ms, 在所有 C++ 提交中击败了44.78%的用户
内存消耗:23.2 MB, 在所有 C++ 提交中击败了8.56%的用户
*/
class Solution {
	vector<vector<int>> ans;
	vector<int> tmp;
	void dfs(TreeNode* root, int sum)
	{
		if(root)
		{
			sum -= root -> val;
			tmp.push_back(root -> val);
			if(root -> left)
			{
				dfs(root -> left, sum);
			}
			tmp.pop_back();
			if(root -> right)
			{
				dfs(root -> right, sum);
			}
		}
		if(sum == 0)
		{
			ans.push_back(tmp);
		}
	} 
public:
    int pathSum(TreeNode* root, int sum) {
        if(root == nullptr)
        	return 0;
        dfs(root, sum);
        int t = pathSum(root -> left, sum) + pathSum(root -> right, sum);
        return ans.size();
    }
};

对暴力进行优化,使用哈希表记录当前访问到的前缀和(因为查找时间为O(1))
如果当前的前缀和减去要求的sum在哈希表中存在,说明是有这样的路径刚好为sum的

/*
[1]
0
93 / 114 个通过测试用例

[0,1,1]
1
96 / 114 个通过测试用例
*/
class Solution {
	int ans;
	void dfs(TreeNode* root,unordered_map<int, int>& Hash, int sum, int cur)
	{
		if(root != nullptr)
		{
			cur += root -> val;
			Hash[cur]++;
            if(Hash[cur - sum])
            {
                ans++;
            }
			dfs(root -> left, Hash, sum, cur);
			dfs(root -> right, Hash, sum, cur);
		}
	} 
public:
    int pathSum(TreeNode* root, int sum) {
        if(root == nullptr)
        	return 0;
        unordered_map<int, int> Hash;
        Hash[0] = 1;//前缀和为0的有一条(即根节点root) 
        dfs(root, Hash, sum, 0);
        return ans;
    }
};

不明白,我的回溯总是会出错,那就像题解那样写成递归吧

/*
执行用时:12 ms, 在所有 C++ 提交中击败了89.10%的用户
内存消耗:19.8 MB, 在所有 C++ 提交中击败了15.36%的用户
*/ 
class Solution {
	int dfs(TreeNode* root,unordered_map<int, int>& Hash, int sum, int cur)
	{	
		if(root == nullptr)
		{
			return 0; 
		}
		int ans = 0; 
		cur += root -> val;
        if(Hash[cur - sum])
        {
            ans+= Hash[cur - sum];
        }
        Hash[cur]++;
		ans += dfs(root -> left, Hash, sum, cur);
		ans += dfs(root -> right, Hash, sum, cur);
		Hash[cur]--;//因为传的是引用,不改回去会影响上一层 
		return ans;
	} 
public:
    int pathSum(TreeNode* root, int sum) {
        if(root == nullptr)
        	return 0;
        unordered_map<int, int> Hash;
        Hash[0] = 1;//前缀和为0的有一条(即根节点root) 
        return dfs(root, Hash, sum, 0);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值