zoukankan      html  css  js  c++  java
  • 力扣437.路径总和III

    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 -> 1

    思路一:双重递归

    写法一:

     1 class Solution {
     2     public boolean flag = false;
     3     public int cnt = 0, cntSum = 0;
     4     public int pathSum(TreeNode root, int sum) {
     5        preTraversal(root, sum);
     6        return cntSum;
     7     }
     8 
     9     // 回溯每个结点判断从根节点开始往下是否存在等于sum的路径
    10     public void traceBack(TreeNode root, int nowSum, int sum){
    11         if(root != null){
    12             nowSum += root.val;
    13             if(sum == nowSum){
    14                 cnt++;
    15             }
    16             traceBack(root.left, nowSum, sum);
    17             traceBack(root.right, nowSum, sum);
    18         }
    19     }
    20 
    21     // 遍历树的所有结点,对每个结点判断从根节点开始往下是否存在等于sum的路径
    22     // 前序递归遍历树节点
    23     public void preTraversal(TreeNode root, int sum){
    24         if(root != null){
    25             cnt = 0;
    26             traceBack(root, 0, sum);
    27             cntSum += cnt;
    28             preTraversal(root.left, sum);
    29             preTraversal(root.right, sum);
    30         }
    31     }
    32 }

    力扣测试时间为31ms, 空间为39.2MB

    另一中稍微简洁一点的写法是:

     1 class Solution {
     2     public int pathSum(TreeNode root, int sum) {
     3        if(root == null){
     4            return 0;
     5        }
     6        // 求出以root为根和为sum的的路径条数
     7         int result = traceBack(root, sum);
     8        // 递归以root.left为根和为sum的的路径条数
     9        int left = pathSum(root.left, sum);
    10        // 递归以root.right为根和为sum的的路径条数
    11        int right = pathSum(root.right, sum);
    12        return result + left + right;
    13     }
    14 
    15     // 回溯每个结点判断从根节点开始往下是否存在等于sum的路径
    16     public int traceBack(TreeNode root, int sum){
    17         if(root == null){
    18             return 0;       // 到达根节点直接返回0
    19         }
    20         sum -= root.val;
    21         int result = sum == 0 ? 1 : 0;
    22         // 加上包含左右根节点的路径
    23         return result + traceBack(root.left, sum) + traceBack(root.right, sum);
    24     }
    25 }

    力扣测试时间为31ms, 空间为39.7MB(可以看到两种写法的时间都差不多,毕竟都是进行先序遍历,对每个结点再已它为根进行一次前序遍历)

    复杂度分析:

    时间复杂度:先进行先序遍历,对每个结点再已它为根进行一次前序遍历,所以时间复杂度为O(n^2)

    空间复杂度:在最坏情况下,即树变成单链表时,栈的最大为n^2, 所以空间复杂度为O(n^2),

    思路二:(不太懂,以后回来看)

    可以理解为以当前结点为最终叶子结点向上追溯,路径上的任一结点为根节点到当前结点的路径和为sum的路径个数。 然后以同样的方法以自己的孩子结点为最终叶子结点计算。

     1 class Solution {
     2     public int pathSum(TreeNode root, int sum) {
     3         // 把以当前结点为终止结点的路径和加入到数组中
     4         return helper(root, sum, new int[1000], 0);    // 0表示刚开始的终结结点为0
     5     }
     6     public int helper(TreeNode root, int sum, int[] array, int p){
     7         if(root == null){
     8             return 0;
     9         }
    10         // 判断以当前根节点为终止结点是否存在满足要求的路径
    11         // 当前结点既是根节点也是终止结点
    12         int temp = root.val;
    13         int cnt = (temp == sum ? 1 : 0);
    14         // 把每个结点都作为开始结点,判断结点到当前结点是否符合要求
    15         for(int i = p - 1; i >= 0; i--){
    16             temp += array[i];
    17             cnt += (temp == sum ? 1 : 0);
    18         }
    19         array[p] = root.val;
    20         // 求出以左右子节点为终止结点,求出符合要求的路径数量
    21         int cnt1 = helper(root.left, sum, array, p + 1);
    22         int cnt2 = helper(root.right, sum, array, p + 1);
    23         return cnt1 + cnt2 + cnt;
    24     }
    25 
    26 }

    力扣测试时间为4ms, 空间为39.6MB

    复杂度分析:

    时间复杂度:虽然变成了单递归,但是复杂度仍然是O(n^2)

    空间复杂度:栈的深度最大可大n, 所以空间复杂度为O(n)

    思路参考:

    https://leetcode-cn.com/problems/path-sum-iii/solution/javajie-fa-shi-jian-100-kong-jian-93-by-xiao-chao-/

  • 相关阅读:
    Sql Server2000里面获得数据库里面所有的用户表名称 和对应表的列名称
    c#开发windows应用程序几个小技巧
    "Unexpected Error 0x8ffe2740 Occurred" Error Message When You Try to Start a Web Site
    注册asp.net到iis
    O/R Mapping 影射文件生成的一点研究(暂时放在这里,实现以后再进行总结)
    WMI使用集锦
    NHibernate快速指南
    项目打包以前需要删除的文件
    Asp.Net 学习资源列表
    精彩Blog
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13137618.html
Copyright © 2011-2022 走看看