二叉树路径和问题

来源:互联网 发布:我的淘宝回收站在哪里 编辑:程序博客网 时间:2024/05/16 16:08

今天回顾了一下二叉树给定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;}





0 0
原创粉丝点击