二叉树中和为某一值的路径

来源:互联网 发布:小额贷款那个软件最好 编辑:程序博客网 时间:2024/06/11 19:34

题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶节点所经过的结点形成一条路径。二叉树的定义如下:

struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;};

二叉树中我们最为熟悉操作莫过于各种遍历了,前序遍历(根左右),中序遍历(左根右),后序遍历(左右根)和层次遍历。而真正笔试题很少会直接考察二叉树的遍历的,而是需要我们会利用二叉树的遍历解决相关问题。最近因为这题思考良久,一直没得出合理的解决方案。期间反映出我对二叉树的操作还是很不熟悉!


对于上图和为20的路径包括{10,8,2},{10,6,3,1}和{10,6,4}。为了找出这些路径,我们来分析一下寻找流程,并尽量用上我们熟悉的二叉树遍历。由于需要的路径是从根节点到叶子节点打印,感觉上符合前序遍历!先走一遍,首先我们需要一个容器保存路径arr和一个遍历保存路径的节点和curNumber

1.遇到根节点10,将10放到路径中,curNumber = 10,此时路径为{10};

2.左结点不为空,访问左结点8,8保存到路径中,curNumber = 10+8 = 18,此时路径为{10,8};

3.左结点不为空,继续访问左结点5,5保存到路径中,curNumber = 18+5 = 23,此时路径为{10,8,5};

4.左右结点都为空,说明该节点为叶子结点,检查当前的路径值curNumber != 20,不是需要的路径不保存;

5.此时需要返回,删除路径中的末尾结点5,同时路径和减去末尾结点值5,回到结点8,curNumber = 18,此时结点路径为{10,8};

6.结点8的右子树不为空,访问右结点2,将2放到路径中,curNumber = 18+2 = 20,此时路径为{10,8,2};

7.结点2的左右子树都为空,结点2为叶子结点,当前的curNumber == 20,说明此时的路径为我需要的路径!将此时的路径保存起来(或者直接打印);当前路径中删除节点2,curNumber 减去当前节点的值2,返回到节点8;

8.继续将结点8从当前路径中删除,当前路径值减去8,则当前路径为{10},路径值为10;

9.访问结点10的右子树。。。

观察上述过程和前序遍历完全一致,只是中间多了路径的保存和路径值的判断。根据上述思想,我们可以得到下面的代码:

    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {        vector<vector<int> > pathArr;<span style="white-space:pre"></span>//保存所有的合法路径        vector<int> currentPath;<span style="white-space:pre"></span>//当前的路径        int currentNumber = 0;<span style="white-space:pre"></span>//当前的路径和        if(root!=NULL)        FindValidPath(root,expectNumber,pathArr,currentPath,currentNumber);                return pathArr;    }        void FindValidPath(TreeNode* root,int expectNumber,vector<vector<int>>& pathArr,                       vector<int> &curPath,int& curNumber){        if(root==NULL)            return;                curNumber += root->val;//更新路径值        curPath.push_back(root->val);//更新路径                if(root->left == NULL && root->right == NULL){//如果是根节点,进行路径值的判断            if(expectNumber == curNumber){                pathArr.push_back(curPath);//保存路径            }            curPath.pop_back();//最后一个节点出栈            curNumber -= root->val;            return;        }        FindValidPath(root->left,expectNumber,pathArr,curPath,curNumber);//处理左子树        FindValidPath(root->right,expectNumber,pathArr,curPath,curNumber);//处理右子树                curPath.pop_back();//对处理完的非叶子节点出栈,并更新当前路径和路径值        curNumber -= root->val;    }

最后推荐一个适合毕业生刷笔题练手的网站——牛客网(http://www.nowcoder.com/),本文讲的题目在该网站上也能找到。

0 0
原创粉丝点击