原题
https://leetcode.com/problems/path-sum-ii/。
Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
翻译:和第一题一样,不过这一次的输出是多有的符合条件的路径。
思路
这一题一样用递归的方法,还是比较简单的(每次递归记录剩下的值,以及已经走过的节点即可)。
我们这里尝试不用递归,而是用迭代的方法来解决这个问题。
这里我们采用后续遍历的框架,然后明确几个问题:后续遍历所用的栈就是目前的路径,我们维护这个栈的值的和,不断和Sum作对比。
后续遍历的过程中,只要有做儿子,就一定是不断往坐下走的,所以只要满足右儿子是空,那么就是叶节点的了,那么这个时候就该对Sum进行判断了,如果相等,那么保存栈中记录的路径的节点。
代码
/**
* 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 {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> theVector;
if(root == NULL)
{
return theVector;
}
list<TreeNode*> theList;
int theSum = 0;
TreeNode* temp = root;
TreeNode* previsited = NULL;
while(temp != NULL || !theList.empty())
{
while(temp != NULL)
{
theList.push_back(temp);
theSum += temp->val;
temp = temp->left;
}
temp = theList.back();
if(temp->right == NULL)
{
if(temp->left == NULL && theSum == sum)
{
vector<int> tempVector;
list<TreeNode*>::iterator theIter;
for(theIter=theList.begin(); theIter!=theList.end(); theIter++)
{
tempVector.push_back((*theIter)->val);
}
theVector.push_back(tempVector);
}
previsited = temp;
theList.pop_back();
theSum -= temp->val;
temp = NULL;
}
else if(temp->right == previsited)
{
previsited = temp;
theList.pop_back();
theSum -= temp->val;
temp = NULL;
}
else
{
temp = temp->right;
}
}
return theVector;
}
};
为了便于大家对比参考,这里列出后续遍历的代码框架:
参考了这位仁兄的博客:
http://blog.csdn.net/hackbuteer1/article/details/6583988
这篇博客总结了二叉树递归和非递归的各种遍历,大家可以去看看。
void PostOrder_Nonrecursive1(BiTree T) // 后序遍历的非递归
{
stack<BiTree> S;
BiTree curr = T ; // 指向当前要检查的节点
BiTree previsited = NULL; // 指向前一个被访问的节点
while(curr != NULL || !S.empty()) // 栈空时结束
{
while(curr != NULL) // 一直向左走直到为空
{
S.push(curr);
curr = curr->lchild;
}
curr = S.top();
// 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
if(curr->rchild == NULL || curr->rchild == previsited)
{
cout<<curr->data<<" ";
previsited = curr;
S.pop();
curr = NULL;
}
else
curr = curr->rchild; // 否则访问右孩子
}
}