23.二叉树中和为某一值的路径(做第二遍时感觉仍有难度,第三次做还是要看一下思路)

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

题目描述

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
牛客网不给测试用例让我感到很迷惑啊。。再次提醒自己,vector是否为空用vector.empty()判断!
// 24.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <vector>
using namespace::std;

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 exp) {
		vector<vector<int>> retVec;
		if (root == NULL)return retVec;
		vector<int> path;
		int cur = 0;
		recursive(root, retVec, path, exp, cur);
		return retVec;
	}

	void recursive(TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int sum, int& cur) {
		path.push_back(root->val);
		cur = cur + root->val;
		bool isLeaf = (root->left == NULL) && (root->right == NULL);
		if (isLeaf && sum == cur) {
			retVec.push_back(path);
		}

		if (root->left != NULL) {
			recursive(root->left, retVec, path, sum, cur);
		}
		if (root->right != NULL) {
			recursive(root->right, retVec, path, sum, cur);
		}
		path.pop_back();
		cur -= root->val;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	TreeNode* root = new TreeNode(10);
	TreeNode* rootLeft = new TreeNode(5);
	TreeNode* rootRight = new TreeNode(12);
	TreeNode* leftLeft = new TreeNode(4);
	TreeNode* leftRight = new TreeNode(7);

	root->left = rootLeft;
	root->right = rootRight;
	rootLeft->left = leftLeft;
	rootLeft->right = leftRight;

	Solution s;
	s.FindPath(NULL, 22);
	return 0;
}

第二次做:
这道题的本质是二叉树的前序遍历,path用来保存路径,cur以引用形式保存当前累加的路径值。计算工作交由recursive函数完成。
先写主函数:
class Solution {
public:
    vector<vector<int> > FindPath(TreeNode* root,int sum) {
        vector<vector<int>> retVec ;
		if ( root == NULL ) return retVec ;
        
        vector<int> path ;
        int cur = 0 ;
        
        recursive( root, retVec, path, cur, sum ) ;
        
        return retVec ;
    }
};

再写递归函数,递归函数的本质是前序遍历,所以我们先把前序遍历的架子搭起来:
    void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int& cur, int sum ) {
        if ( root == NULL ) return ;// 递归退出条件
        
        // 这里写处理代码
        recursive( root->left, retVec, path, cur, sum ) ; // 左递归
        recursive( root->right, retVec, path, cur, sum ) ; // 右递归

    }

再加上处理代码:
    void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int& cur, int sum ) {
        if ( root == NULL ) return ;
        
        cur += root->val ; // 处理代码
        path.push_back( root->val ) ; // 处理代码
        
        bool isLeaf = ( root->left == NULL ) && ( root->right == NULL ) ; // 处理代码
        if ( isLeaf && sum == cur ) { // 处理代码
            retVec.push_back( path ) ; // 处理代码
        }
        
        recursive( root->left, retVec, path, cur, sum ) ;
        recursive( root->right, retVec, path, cur, sum ) ;
    }



往往到这里就结束了,但是这道题有点特殊,当遍历到叶子节点,但是路径值不等于sum时,要弹出当前节点值。
    void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int& cur, int sum ) {
        if ( root == NULL ) return ;
        
        cur += root->val ;
        path.push_back( root->val ) ;
        
        bool isLeaf = ( root->left == NULL ) && ( root->right == NULL ) ;
        if ( isLeaf && sum == cur ) {
            retVec.push_back( path ) ;
            //return ;
        }
        
        recursive( root->left, retVec, path, cur, sum ) ;
        recursive( root->right, retVec, path, cur, sum ) ;
        
        path.pop_back() ; // 弹出当前叶子节点的值
        cur -= root->val ; // 路径值减去当前叶子节点的值
    }

第三次做:
/*
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 expNum) {
    	vector<vector<int>> retVec ;
        if ( root == NULL ) return retVec ;
        
    	vector<int> path ;
        int cur = 0 ;
        
        recursive( root, retVec, path, expNum, cur ) ;
        
        return retVec ;
    }
    
    void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int &expNum, int cur ) {
        if ( root == NULL ) return ;
        
        cur += root->val ;
        path.push_back( root->val ) ;
        bool isLeaf = ( root->left == NULL ) && ( root->right == NULL ) ;
        if ( isLeaf == true && cur == expNum ) {
            retVec.push_back( path ) ;
        }
        
        recursive( root->left, retVec, path, expNum, cur ) ;
        recursive( root->right, retVec, path, expNum, cur ) ;
        
        cur -= root->val ;
        path.pop_back() ;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值