剑指offer -- 二叉树中和为某一值的路径

题目:

输入一棵二叉树和一个整数,返回二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
在这里插入图片描述

返回:
[
[5,4,11,2],
[5,8,4,5]
]

分析:
由于路径是从根节点出发到叶节点,也就是说路径总以根节点为起始点,因此我们需要遍历根节点,使用前序遍历,因为只有前序遍历首先访问根节点。

我们以如图所示的例子来慢慢分析,首先从节点5开始,然后访问到节点4,路径中现在有两个节点5、4 ,然后到节点11、7,路径中有4个节点,7是叶子节点,但是路径中的节点值的和并不等于目标值,所以这条路行不通。我们需要返回到这个节点的上一级节点,同时返回到上一级节点也就证明这个
节点不存在于路径中了,需要删除这个节点在路径中的值,每一次从子节点 返回到父亲节点时都需要删除子节点存在于路径中的值,则现在路径里存在 5、4、11,访问到节点2,路径中5、4、11、2,和刚好等于目标值,且2为叶子节点,符合我们的要求,这条路径保存。

删除节点2 路径里5、4、11、11的左右都访问完毕,删除11回到4,4的左边访问完毕 ,右边没有节点 , 删除4,回到5,然后把8添加到路径中 ,再添加13,路径里5、8、13,虽然13是叶子节点,但是路径中节点值得和不等于目标值,删除13,返回到上一级节点,把4、5添加到路径中,5、8、4、5 路经中和为目标值 ,且5为叶子节点,保存路径,删除5,返回到上一级节点 把1添加到路径中,5、8、4、1,虽然1为叶子节点,但是路径和并不等于目标值。至此,所有节点都遍历完毕,递归调用结束。

分析完前面的具体例子,我们应该发现了一些规律,当用前序遍历的方式访问到某一节点时,我们把该节点添加到路径中,如果该节点为叶节点且路径中节点值的和为目标值 ,则保存路径。如果不是叶节点,则继续访问它的子节点。当前节点访问完后(左边和右边已经全部访问过),递归函数将会自动回到它的父节点。因此我们在函数退出以前需要把路径中的当前节点删除。

代码:

class Solution {
    
    
private:
	vector<int>path;  //保存路径
	vector<vector<int>>ans; //保存正确的路径
public:
	vector<vector<int>> pathSum(TreeNode* root, int target) {
    
    
		findpath(root,target);
		return ans;
	}

	void findpath(TreeNode *node,int target){
    
    

		if(node != NULL){
    
    
			target = target-node->val;

			path.push_back(node->val);

			if(target == 0 && node->left == NULL && node->right == NULL){
    
    
				ans.push_back(path);
			}

			else{
    
     
				findpath(node->left,target);

				findpath(node->right,target);
			}
			path.pop_back();
		}
	}
};

おすすめ

転載: blog.csdn.net/scarificed/article/details/120533114