【PHP解法==LeetCode(二叉树中的递归2-路径之和)】路径总和(112.113.437) && 404.左叶子之和 && 129. 求根到叶子节点数字之和 && 257.二叉树的所有路径

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010365335/article/details/87871564

目录

路径总和I.II.III(112.113.437)

112.路径总和.II.III(112.113.437)

113.路径总和II

437.路径总和III

404.左叶子之和

129. 求根到叶子节点数字之和

257.二叉树的所有路径


路径总和I.II.III(112.113.437)

112.路径总和.II.III(112.113.437)

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 
给定如下二叉树,以及目标和 sum = 22

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

解法:从根节点递归到叶子节点,依次相加,得到一个与sum一样的值则返回true,否则继续递归,直到树空

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     public $val = null;
 *     public $left = null;
 *     public $right = null;
 *     function __construct($value) { $this->val = $value; }
 * }
 */
class Solution {
    function hasPathSum($root, $sum) {
        if($root == null) return false;    //当树为空时,直接返回false
        if($root->left == null && $root->right == null) return $root->val == $sum;   //当值等于sum时,即已找到结果
        //递归左右子树,参数sum = 当前的sum - 当前节点(即下一节点的父节点)的值
        return $this->hasPathSum($root->left, $sum - $root->val) || $this->hasPathSum($root->right, $sum - $root->val);
    }
}

113.路径总和II

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 sum = 22

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
返回:[
   [5,4,11,2],
   [5,8,4,5]
]

与112区别:该题需要额外记录满足条件的所有路径

class Solution {
    function pathSum($root, $sum) {
        if($root == null) return [];            //当树为空时,返回空数组
        $res = [];
        $this->getAllPath($root,$sum,[],$res);  //递归函数:获得所有路径
        return $res;
    }
    public function getAllPath($root,$sum,$path,&$res){
        //参数(节点,剩余的sum,已经取得的路径序列,引用传值结果数组)
        if($root == null) return;   //树为空,直接返回
        $num = $root->val;          //将节点的值压入路径中,方便之后使用
        $path[] = $num;
        if($root->left == null && $root->right == null && $root->val == $sum){
            //当该节点是叶子节点时,且节点的值=sum,即已找到结果路径,将路径path压入结果数组中
            $res[] = $path;
        }else{
            //否则将继续进行递归
            if($root->left != null){
                $this->getAllPath($root->left,$sum - $num,$path,$res);
            }
            if($root->right != null){
                $this->getAllPath($root->right,$sum - $num,$path,$res);
            }
        }
    }
}

437.路径总和III

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

返回 3。和等于 8 的路径有:

1.  5 -> 3
2.  5 -> 2 -> 1
3.  -3 -> 11

与102区别:不要求从根节点到叶子节点,只要是连续的就行,只需返回结果数量

解法:从根节点开始,依次从每个节点遍历到根节点,求路径和是否=sum,取结果

class Solution {
    function pathSum($root, $sum) {
        if($root == null) return 0;//树为空,则返回0
        $queue = [$root];          //利用队列,层次遍历,再进行递归
        $times = 0;                //记录路径数量
        while(!empty($queue)){
            $curNode = array_shift($queue);                 //取出当前节点
            $times += $this->dfs($curNode,$sum);            //递归:进行深度优先搜索
            if($curNode->left) $queue[] = $curNode->left;   //左子树不为空,将左子树入队
            if($curNode->right) $queue[] = $curNode->right; //右子树不为空,将右子树入队
        }
        return $times;
    }
    public function dfs($node, $sum){
        $res = 0;
        if($node == null) return $res;      //若节点为空,返回0
        $num = $node->val;
        if($num == $sum) $res = 1;          //若节点的值=sum,则记录成功1条
        //不到叶子节点还不能返回res,因为节点的值可能为负数,可能下方运算后,还可以得到结果
        if($node->left == null && $node->right == null) return $res;       //若该节点为叶子节点,则直接返回结果res次数
        $res += $this->dfs($node->left,$sum-$num) + $this->dfs($node->right,$sum-$num); //左右孩子递归,sum取减节点的值后的值
        return $res;
    }
}

404.左叶子之和

计算给定二叉树的所有左叶子之和。

示例:

    3
   / \
  9  20
    /  \
   15   7

在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

该题比较简单,只需要递归遍历取得左叶子节点,相加即可

class Solution {
    function sumOfLeftLeaves($root) {
        if($root == null) return 0;     //当树为空时,返回0
        if($root->left == null && $root->right == null) return 0;   //当节点为叶子节点时,返回0,因为该节点可能是右节点
        //左叶子节点在这条判断中取值:当该节点存在左节点,且该左节点为叶子结点时,则可取该左孩子的值进结果中
        if($root->left && $root->left->left == null && $root->left->right == null){
            return $root->left->val + $this->sumOfLeftLeaves($root->right);                 //取左孩子的子,并继续递归右子树
        return $this->sumOfLeftLeaves($root->left) + $this->sumOfLeftLeaves($root->right);  //递归左右子树
    }
}

129. 求根到叶子节点数字之和

给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。

例如,从根到叶子节点路径 1->2->3 代表数字 123

计算从根到叶子节点生成的所有数字之和。

说明: 叶子节点是指没有子节点的节点。

示例 1:

输入: [1,2,3]
    1
   / \
  2   3
输出: 25
解释:从根到叶子节点路径1->2代表数字12.
从根到叶子节点路径1->3代表数字13.
因此,数字总和 = 12 + 13 =25.

示例 2:

输入: [4,9,0,5,1]
    4
   / \
  9   0
 / \
5   1
输出: 1026
解释:从根到叶子节点路径4->9->5代表数字 495.
从根到叶子节点路径4->9->1代表数字 491.
从根到叶子节点路径4->0代表数字 40.

解法:连接所有路径,并相加

class Solution {
    /**
     * @param TreeNode $root
     * @return Integer
     */
    private $sum = 0;                   //结果之和
    function sumNumbers($root) {
        if($root == null) return 0;     //树为空,直接返回0
        $this->findSum($root,'');       //递归(节点,路径)
        return $this->sum;
    }
    private function findSum($root,$path){
        if($root == null) return null;                      //当节点为空,返回空
        $path = $path.$root->val;                           //取当前路径,连接最新的值
        if($root->left == null && $root->right == null){    //当该节点为叶子节点时,将结果sum加上路径对应的值
            $this->sum = $this->sum + $path;
        }
        if($root->left) $this->findSum($root->left,$path);  //没找到叶子节点则继续递归遍历左右子树
        if($root->right) $this->findSum($root->right,$path);
        return ;
    }
}

257.二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:
   1
 /   \
2     3
 \
  5
输出: ["1->2->5", "1->3"]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

解法:遍历左右孩子,从叶子节点回溯路径到根节点,其间按题目要求进行链接

class Solution {
    function binaryTreePaths($root) {
        if($root == null) return [];        //当节点为空,返回空数组
        if($root->left == null && $root->right == null) return [(string)$root->val];  //该节点为叶子节点时,返回一个元素的数组
        $res = [];  //记录结果
        //左右孩子分别递归遍历/
        if($root->left != null){                                
            $left = $this->binaryTreePaths($root->left);         //左子树进行递归
            $len = count($left);                                
            for($i = 0;$i<$len;++$i){
                $res[] = (string)$root->val . '->' . $left[$i];  //对取得的值按题目要求进行连接
            }
        }
        if($root->right != null){
            $right = $this->binaryTreePaths($root->right);       //左子树进行递归
            $len = count($right);
            for($i = 0;$i<$len;++$i){
                $res[] = (string)$root->val . '->' . $right[$i]; //对取得的值按题目要求进行连接
            }
        }
        return $res;
    }
}

猜你喜欢

转载自blog.csdn.net/u010365335/article/details/87871564
今日推荐