牛客网《剑指Offer》编程 24.二叉树中和为某一值的路径

题目描述

输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)。

解题思路

由于最后要得到从根到叶子节点的路径,因此使用二叉树的前序遍历算法。

将当前节点值加入sum中,并且将当前节点加入路径中。

如果sum值恰好等于要求的和,且该节点为叶子节点,则将该路径存储在结果容器中;

如果当前节点不是叶子节点,则在其子树不空的情况下访问子树。

由于节点访问结束之后,会回到其父节点。因此手动设置将当前的节点从路径中弹出,并且在sum减去当前节点值。

代码实现

递归

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    vector<vector<int> > res;
    void FindPath(TreeNode* root,vector<int> path,int expectNumber,int currentNumber){
        //先序遍历,根左右。
        currentNumber+=root->val;
        path.push_back(root->val);
        bool isLeaf=!root->left&&!root->right;
        if(isLeaf&&currentNumber==expectNumber){
            res.push_back(path);
        }
        if(root->left){
            FindPath(root->left,path,expectNumber,currentNumber);
        }
        if(root->right){
            FindPath(root->right,path,expectNumber,currentNumber);
        }
        currentNumber-=root->val;
        path.pop_back();
    }
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        if(!root){
            return res;
        }
        int currentNumber=0;
        vector<int> path;
        FindPath(root,path,expectNumber,currentNumber);
        return res;
    }
};

非递归:如果当前节点做节点不为空,则一直访问左节点。当左节点为空时,访问未访问过的右节点。

如果右节点被访问过或者是空节点,则回溯到当前节点的父节点。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        vector<vector<int> > res;
        if(root==nullptr){
            return res;
        }
        stack<TreeNode* > stk;
        vector<int> path;
        TreeNode* curr=root;
        TreeNode* last=nullptr;
        int sum=0;
        stk.push(root);
        while(!stk.empty()){
            if(curr==nullptr){//如果左节点为空
                TreeNode* temp=stk.top();//回溯父节点
                if(temp->right!=nullptr&&temp->right!=last){
                    curr=temp->right;//如果父节点的右节点没有被访问过且不为空,则访问右节点
                }else{//如果当前节点的右节点被访问过或者为空,保存父节点在last中
                    last=temp;
                    path.pop_back();//这里下面三步是回溯当前temp的父节点。没有改变curr的值。
                    sum-=temp->val;
                    stk.pop();
                }
                
            }else{//如果当前节点不为空,则访问当前节点
                if(curr!=root){
                    stk.push(curr);
                }
                path.push_back(curr->val);//将该节点加入path中
                sum+=curr->val;//将该节点值加入当前和
                if(sum==expectNumber&&!curr->left&&!curr->right){
                    res.push_back(path);
                }
                curr=curr->left;//先序遍历,遍历完当前节点之后遍历当前节点的左节点。
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/eriHanami/article/details/82814300