二叉树路径和问题

本文深入分析了一段用于解决二叉树路径和问题的代码,发现了路径记录逻辑上的错误,并提出了解决方案。通过改进路径回退机制,确保了正确检测路径和。同时,引入了基于先序递归的算法,使用vector模拟栈结构,成功解决了路径记录问题。此方法不仅提高了算法效率,还避免了栈操作的复杂性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天回顾了一下二叉树给定sum的问题,逻辑还是有问题,本以为对的,写了如下的代码

bool hasPathSum(TreeNode *root, int sum) {
        if(root==NULL && sum==0) return true;
        TreeNode* p=root;
        stack<TreeNode* > S;
        int path=0;
        while(!S.empty()||p!=NULL)
        {
            while(p!=NULL)
            {
                S.push(p);
                path+=p->val;
                p=p->left;
            }
            if(path==sum) return true;
            p=S.top();
	    S.pop();
            if(p->left!=NULL)
                path-=p->left->val;
            p=p->right;
        }
        return false;
    }
但是发现其实,path记录的时候有问题,尤其是右子树回退的时候是回退两次,所以这个就挂了

一开始分析,发现这里面三个数据结构要跟踪,p, Stack内容,path值,所以还是没弄清楚,除了bug

确实while结束之后,就是访问叶子结点的位置,而且左子树回退的时候,就是path-=p->left->val,如果left有的话,没有就不减。

但是我用数据跑了下,右边的都detect不到,分析见下图



也就是说,从右子树4回退,指针回一次回退两次到1,因为之前的2在走2->4的时候,已经从stack pop出来了,所以回到1的时候,只减了2,没减4,就在这时我突然想到可以直接再- p->left->right->val啊,之前怎么没想到,就这么在写博客的时候想到了解决方案,但是不确定是否完全正确。感觉要么从左子树回退,看是否空来- 要么右子树回退,就是回退两次,然后path- = 两次

但是从leetcode反馈来看,似乎还有问题。

分析出来,似乎还有从右子树的右子树回退两次的情况,因此还是会挂,所以这条路不确定是否可以走通


于是乎回顾了当年4月份的帖子,写的基于先序递归算法的pathsum代码,然后记录所有路径也是,但是记录路径可能用vector来模拟栈比较好,可以直接push_back,stack没有迭代器,没法copy到一个vector,除非一个一个pop出来,放在queue里,但是还要push回去,很麻烦,所以vector了。另外vector还可以模拟类似队列的结构,例如编程之美层序遍历打印层结束的代码;

struct TreeNode {
    int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };

bool HasPathSum=false;
vector<vector<int> >allpathvec;
vector<int> pathvec;
void PreOrder(TreeNode* root, int sum, int &path)
{
	if(root!=NULL)
	{
		//cout<<root->val;
		path+=root->val;
		pathvec.push_back(root->val);
		if(root->left==NULL && root->right==NULL && path==sum)
		{
			HasPathSum=true;
			allpathvec.push_back(pathvec);
		}
		PreOrder(root->left,sum,path);
		PreOrder(root->right,sum,path);
		path-=root->val;
		pathvec.pop_back();
	}
}
vector<vector<int> > hasPathSum_recursivecall(TreeNode *root, int sum)
{
	HasPathSum=false;
	int path=0;
	PreOrder(root,sum,path);
	return allpathvec;
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值