一、题目描述
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。
示例1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
①树中节点总数在范围 [0, 5000] 内
②-1000 <= Node.val <= 1000
③-1000 <= targetSum <= 1000
二、思路分析
注:思路分析中的一些内容和图片参考自力扣各位前辈的题解,感谢他们的无私奉献
思路
本问题是典型的二叉树方案搜索问题,使用回溯法解决,其包含 先序遍历 + 路径记录 两部分。
先序遍历:按照 “根、左、右” 的顺序,遍历树的所有节点。
路径记录:在先序遍历中,记录从根节点到当前节点的路径。当路径为根节点到叶节点形成的路径且各节点值的和等于目标值 sum 时,将此路径加入结果列表。
算法流程:
①pathSum函数:
初始化:为结果列表res
,路径列表path
和记录每行元素个数的列表returnColusmSize
分配空间
运行:从根结点开始执行recur
函数
返回值:返回res
②recur函数:
判断当前节点是否为空,如果为空则直接返回
将当前节点的值记录到path中,并将target减去当前节点值
判断当前节点是否为叶节点、target是否为0
----如果是,则为res的当前行分配空间、将路径记录到res当前行、行数+1
----如果不是,则递归处理左右孩子
进行回溯
案例分析:
复杂度分析:
时间复杂度 O ( N ) \rm{O(N)} O(N):N
为二叉树的节点数,先序遍历需要遍历所有节点
空间复杂度 O ( N ) \rm{O(N)} O(N):最差情况下,即树退化为链表时,path
存储所有树节点,使用O(N)
额外空间。
三、整体代码
整体代码如下
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
void recur(struct TreeNode* root, int target, int* returnSize, int** returnColumnSizes, int nums, int* path, int** res){
//如果当前节点为空,则直接返回
if(!root){
return;
}
path[nums++] = root->val; //将当前节点值记录到path中
target -= root->val; //将target减去当前节点值
//如果target等于0且当前节点为叶节点,记录此条路径
if(!root->left && !root->right && target == 0){
res[*returnSize] = (int*)malloc(sizeof(int) * nums);
(*returnColumnSizes)[*returnSize] = nums;
for(int i = 0; i < nums; i++){
res[*returnSize][i] = path[i]; //记录路径
}
(*returnSize)++; //行数++
}
else{
//递归处理左右孩子
recur(root->left, target, returnSize, returnColumnSizes, nums, path, res);
recur(root->right, target, returnSize, returnColumnSizes, nums, path, res);
}
nums--; //回溯
}
int** pathSum(struct TreeNode* root, int target, int* returnSize, int** returnColumnSizes){
*returnSize = 0; //初始化行数
//为记录每一行元素个数的returnColumnSizes、路径path、返回的结果res分配内存空间
*returnColumnSizes = (int*)malloc(sizeof(int)*1001);
int* path = (int*)malloc(sizeof(int)*1001);
int** res = (int*)malloc(sizeof(int*)*1001);
int nums = 0; //初始化nums为0,用于记录当前路径有多少个节点
recur(root, target, returnSize, returnColumnSizes, nums, path, res); //从根结点开始进行处理
return res;
}
运行,测试通过