算法系列-第十一题

99 阅读2分钟

题目名称:路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22

输出:true

解释:等于目标和的根节点到叶节点路径如上图所示。

示例 2:

输入:root = [1,2,3], targetSum = 5

输出:false

解释:树中存在两条根节点到叶子节点的路径:

(1 --> 2): 和为 3

(1 --> 3): 和为 4

不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

输入:root = [], targetSum = 0

输出:false

解释:由于树是空的,所以不存在根节点到叶子节点的路径。


/**

* 解法一:递归(先序遍历)

* 思路:

* 既然是检查从根到叶子有没有一-条等于目标值的路径,那肯定需要从根节点遍历到叶子,

* 我们可以在根节点每次往下一层的时候,将sum减去节点值,最后检查是否完整等于0.而

* 遍历的方法我们可以选取二叉树常用的递归先序遍历,因为每次进入一个子节点,更新

* sum值以后,相当于对子树查找有没有等于新目标值的路径,因此这就是子问题

* 时间复杂度:O(n),先序遍历二叉树所有结点

* 空间复杂度:O(n),最坏情况二叉树化为链表,递归栈空间最大为n

*/

function hasPathSum(root: TreeNode | null, targetSum: number): boolean {

if (root == null) return false;

if (root.left == null && root.right == null && root.val === targetSum)

return true;

return (

hasPathSum(root.left, targetSum - root.val) ||

hasPathSum(root.right, targetSum - root.val)

);

}


/**

* 解法二:非递归(DFS)

* 思路:

* 在二叉树中能够用递归解决的问题,很多时候我们也可以用非递归来解决。这里遍历过程

* 也可以使用栈辅助,进行dfs遍历,检查往下的路径中是否有等于sum的路径和。

* 注意,这里仅是dfs,而不是先序遍历,左右节点的顺序没有关系,因为每次往下都是单

* 独添加某个节点的值相加然后继续往下,因此左右节点谁先遍历不管用。

* 时间复杂度:O(n),DFS遍历二叉树所有结点

* 空间复杂度:O(n),最坏情况二叉树化为链表,递归栈空间最大为n

*/

function hasPathSum(root: TreeNode | null, targetSum: number): boolean {

if (root == null) return false;

const treeNodeStack: TreeNode[] = [];

const valueStack: number[] = [];

treeNodeStack.push(root);

valueStack.push(root.val);

  


while (treeNodeStack.length) {

const node = treeNodeStack.pop(); // 弹出相应节点

const valSum = valueStack.pop(); // 获取到该节点为止的路径和

  


// 是叶子结点且当前路径和等于 valSum

if (node.left == null && node.right == null && valSum === targetSum)

return true;

  


// 左节点&对应路径和入栈

if (node.left != null) {

treeNodeStack.push(node.left);

valueStack.push(node.left.val + valSum);

}

  


// 右节点&对应路径和入栈

if (node.right != null) {

treeNodeStack.push(node.right);

valueStack.push(node.right.val + valSum);

}

}

  


return false;

}