Leetcode 437: 二叉树路径总和3(双递归)

Leetcode 437: 二叉树路径总和3(双递归)

问题:

在这里插入图片描述


此题的测试用例表示单节点也算作一条路径,但是在题中并没有说明,这显然是不符合路径定义的


思路:

1.分治双递归:

对于一棵二叉树,路径和等于给定数值的路径包括两种:包含根节点的路径和不包含根节点的路径。由此引出两个递归函数:一个递归函数用于求包含根节点的路径,另一个递归函数用于求不包含根节点的路径

求包含根节点的路径的递归函数:当根节点为空时返回0,否则将sum减去根节点的值,并将减去后的值赋给sum,若为0,证明找到了一条路径,将flag置为1。由于路径包含根节点,因此若存在其他路径,也一定包含左右子树的根节点其中之一,因此接下来对左右子树的根节点递归调用函数自身,函数返回flag+左右子树递归函数的返回值

求不包含根节点的路径的递归函数:当根节点为空时返回0,不包含根节点的路径由包含左右子树根节点的路径和不包含左右子树根节点的路径组成,函数返回值为:递归调用求包含左右子树根节点的路径的递归函数的返回值+对左右子树根节点调用自身(求不包含左右子树根节点的路径的递归函数)的返回值。

主函数返回对根节点分别调用两个递归函数返回值之和

2.单递归(先序遍历的变式):

用一维vector path记录路径,将当前遍历到的节点加入路径中,此时的path记录了从根节点到当前节点的路径,将当前节点当做路径的终点(路径的终点必须为该节点),在path中以当前节点开始向前搜索满足条件的路径和,若搜索到,路径数加1。

对左子树和右子树调用递归函数,将满足条件的路径数加上它们的返回值。

当对左子树和右子树递归完成后,表明包含该节点的路径已经遍历完毕,将该节点从path中弹出

递归函数返回满足条件的路径数

代码:

1.分治双递归:
/**
 * 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:
    int path_include_root( TreeNode* root,int sum ) //包含root的路径数
    {
        if( root==NULL )    
            return 0;
        sum-=root->val;
        int flag;
        flag= sum==0? 1:0;
        return path_include_root( root->left,sum )+path_include_root( root->right,sum )+flag;
    }
    int path_Noinclude_root( TreeNode* root,int sum ) //不包含root的路径数
    {
        if( root==NULL )
            return 0;
        return path_include_root( root->left,sum )+path_include_root( root->right,sum )
                +path_Noinclude_root( root->left,sum )+path_Noinclude_root( root->right,sum );
    } 
    int pathSum(TreeNode* root, int sum) {
        return ( path_include_root(root,sum) + path_Noinclude_root(root,sum) );
    }
};
2.单递归(先序遍历的变式):
/**
 * 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:
    int pretraverse( TreeNode* p,int sum,vector<int> &path )
    {
        if( p==NULL )
            return 0;
        int sum_cur=0;
        int path_num=0;
        path.push_back( p->val );
        for( int i=path.size()-1;i>=0;i-- )
        {
            sum_cur+=path[i];
            if( sum_cur==sum )
                path_num++;
        }
        path_num+=pretraverse( p->left,sum,path )+pretraverse( p->right,sum,path );
        path.pop_back();
        return path_num;
    }
    int pathSum(TreeNode* root, int sum) {
        vector<int> path;
        return pretraverse( root,sum,path );
    }
};

猜你喜欢

转载自blog.csdn.net/qq_44709990/article/details/105909855
今日推荐