我是靠谱客的博主 动听万宝路,这篇文章主要介绍24 二叉树的路径和(Binary Tree Path Sum),现在分享给大家,希望可以做个参考。

文章目录

    • 1 题目
    • 2 解决方案
      • 2.1 思路
      • 2.2 时间复杂度
      • 2.3 空间复杂度
    • 3 源码
      • 3.1 分治法
      • 3.2 遍历法

1 题目

题目:二叉树的路径和(Binary Tree Path Sum)
描述:给定一个二叉树,找出所有路径中各节点相加总和等于给定 目标值 的路径。一个有效的路径,指的是从根节点到叶节点的路径。

lintcode题号——376,难度——easy

样例1:

输入:{1,2,4,2,3},5
输出: [[1, 2, 2],[1, 4]]
说明:
这棵树如下图所示:
	     1
	    / 
	   2   4
	  / 
	 2   3
对于目标总和为5,很显然1 + 2 + 2 = 1 + 4 = 5

样例2:

输入:{1,2,4,2,3},3
输出: []
说明:
这棵树如下图所示:
	     1
	    / 
	   2   4
	  / 
	 2   3
注意到题目要求我们寻找从根节点到叶子节点的路径。
1 + 2 + 2 = 5, 1 + 2 + 3 = 6, 1 + 4 = 5 
这里没有合法的路径满足和等于3。

2 解决方案

2.1 思路

  使用分治法,获取左右子树满足值为目标值-当前节点值的所有路径,然后在每个路径前拼接上当前节点即可组成答案。
  使用遍历法,递归过程中走到每个叶子节点都判断下路径和是否为目标值,相等的话将路径加入答案集合即可。

2.2 时间复杂度

  分治法和遍历法都需要完整遍历整棵树,算法的时间复杂度为O(n)。

2.3 空间复杂度

  算法的空间复杂度为O(1)。

3 源码

3.1 分治法

细节:

  1. 对叶子结点要特殊处理,否则会导致返回空。
  2. 在vector头部插入可以使用insert,合并两个vector也可以使用insert。

C++版本:

/**
* Definition of TreeNode:
* class TreeNode {
* public:
*     int val;
*     TreeNode *left, *right;
*     TreeNode(int val) {
*         this->val = val;
*         this->left = this->right = NULL;
*     }
* }
*/
/**
* @param root: the root of binary tree
* @param target: An integer
* @return: all valid paths
*          we will sort your return value in output
*/
vector<vector<int>> binaryTreePathSum(TreeNode *root, int target) {
    // write your code here
    vector<vector<int>> results;
    if (root == nullptr)
    {
        return results;
    }

    // 处理叶子节点
    if (root->left == nullptr && root->right == nullptr && target == root->val)
    {
        vector<int> temp;
        temp.push_back(root->val);
        results.push_back(temp);
        return results;
    }

    vector<vector<int>> leftResults = binaryTreePathSum(root->left, target - root->val);
    vector<vector<int>> rightResults = binaryTreePathSum(root->right, target - root->val);

    // 将当前节点值插入左右结果的头部
    for (int i = 0; i < leftResults.size(); i++)
    {
        leftResults.at(i).insert(leftResults.at(i).begin(), root->val);
    }
    for (int i = 0; i < rightResults.size(); i++)
    {
        rightResults.at(i).insert(rightResults.at(i).begin(), root->val);
    }
    // 合并左右结果
    results.insert(results.end(), leftResults.begin(), leftResults.end());
    results.insert(results.end(), rightResults.begin(), rightResults.end());

    return results;
}

3.2 遍历法

细节:

  1. 这题使用遍历法,代码稍复杂,对子树遍历时候需要有回溯操作。
  2. 只有左右子树存在的时候才进行递归。

回溯和节点压入并不成对出现,因为节点无论何时都需压入,但子树可能没有,导致不需要回溯。

C++版本:

/**
* Definition of TreeNode:
* class TreeNode {
* public:
*     int val;
*     TreeNode *left, *right;
*     TreeNode(int val) {
*         this->val = val;
*         this->left = this->right = NULL;
*     }
* }
*/
/**
* @param root: the root of binary tree
* @param target: An integer
* @return: all valid paths
*          we will sort your return value in output
*/
vector<vector<int>> binaryTreePathSum(TreeNode * root, int target) {
    // write your code here
    vector<vector<int>> results;
    if (root == NULL)
    {
        return results;
    }
    
    vector<int> path;
    traverse(root, target, path, results);
    return results;
    }

void traverse(TreeNode * root, int remainTarget, vector<int> &path, vector<vector<int>> &results)
{
    if (root == NULL)
    {
        return;
    }

    path.push_back(root->val);

    // 处理叶子节点
    if (root->left == NULL && root->right == NULL && remainTarget == root->val)
    {
        results.push_back(path);
        return;
    }

    // 进入左子树,需要回溯
    if (root->left != NULL)
    {
        traverse(root->left, remainTarget - root->val, path, results);
        path.pop_back(); // 回溯
    }
    // 进入右子树,需要回溯
    if (root->right != NULL)
    {
        traverse(root->right, remainTarget - root->val, path, results);
        path.pop_back(); // 回溯
    }
}

最后

以上就是动听万宝路最近收集整理的关于24 二叉树的路径和(Binary Tree Path Sum)的全部内容,更多相关24内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部