文章目录
- 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 分治法
细节:
- 对叶子结点要特殊处理,否则会导致返回空。
- 在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 遍历法
细节:
- 这题使用遍历法,代码稍复杂,对子树遍历时候需要有回溯操作。
- 只有左右子树存在的时候才进行递归。
回溯和节点压入并不成对出现,因为节点无论何时都需压入,但子树可能没有,导致不需要回溯。
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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复