zoukankan      html  css  js  c++  java
  • LeetCode 437. Path Sum III

    437. Path Sum III

    Description Submission Solutions

    • Total Accepted: 18367
    • Total Submissions: 47289
    • Difficulty: Easy
    • Contributors: Stomach_ache

    You are given a binary tree in which each node contains an integer value.

    Find the number of paths that sum to a given value.

    The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).

    The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

    Example:

    root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
    
          10
         /  
        5   -3
       /     
      3   2   11
     /    
    3  -2   1
    
    Return 3. The paths that sum to 8 are:
    
    1.  5 -> 3
    2.  5 -> 2 -> 1
    3. -3 -> 11

    Subscribe to see which companies asked this question.


    【题目分析】
    给定一颗二叉树,找到二叉树中从上往下所有的和值为目标值的节点序列。不要求必须从根节点开始到叶子结点。

    【思路】
    1. 我们可以遍历二叉树的每一个结点,搜索从这个节点出发的所有满足条件的路径的数目。
    这种方法以某种顺序遍历一棵树中的所有节点,然后计算从这个节点出发的满足条件的路径数。遍历二叉树的时间复杂度为O(N),对于每一个节点,需要以它为根节点找到所有的符合条件的路径,则综合来看时间复杂度为O(N2)。递归栈的最大深度为logN,因此空间复杂度为O(logN)。
    2. So the idea is similar as Two sum, using HashMap to store ( key : the prefix sum, value : how many ways get to this prefix sum) , and whenever reach a node, we check if prefix sum - target exists in hashmap or not, if it does, we added up the ways of prefix sum - target into res.
    For instance : in one path we have 1,2,-1,-1,2, then the prefix sum will be: 1, 3, 2, 1, 3, let's say we want to find target sum is 2, then we will have{2}, {1,2,-1}, {2,-1,-1,2} and {2}ways.
    这是discuss里的一个比较好的方法,时间复杂度得到了优化。
    这个方法的思路是保存从根节点到达当前节点的prefix sum。比如到达当前节点经过的节点val为 1,2,-1,-1,2,那么prefix为1,3,2,1,3. 计算当前节点的prefix sum,然后在前面的所有prefix sum中查找是否存在curSum - target,如果存在,则证明存在这样的点,从这点出发到达当前节点的值正好为target。
     
     
    通过上图,我们明白了这个算法的思想。这个算法通过一个hashmap来保存这样的prefix sum信息。那么多二叉树的分叉,是否需要为每一个分支建立一个HashMap呢?我们并不需要这样做,而是采用回溯的做法,如果当前节点的所有的路径都处理完毕了,则把该节点从HashMap中删除,转而去处理别的节点。在初始的时候我们把(0,1)加入HashMap。这是为了那些curSum正好target情况的出现。

    【java代码1】
     1 /**
     2  * Definition for a binary tree node.
     3  * public class TreeNode {
     4  *     int val;
     5  *     TreeNode left;
     6  *     TreeNode right;
     7  *     TreeNode(int x) { val = x; }
     8  * }
     9  */
    10 public class Solution {
    11     public int pathSum(TreeNode root, int sum) {
    12         if(root == null) return 0;
    13         int res = pathNum(root, sum);
    14         
    15         if(root.left != null) res += pathSum(root.left, sum);
    16         if(root.right != null) res += pathSum(root.right, sum);
    17         
    18         return res;
    19     }
    20     
    21     public int pathNum(TreeNode root, int sum) {
    22         if(root == null) return 0;
    23         int res = 0;
    24         if(root.val == sum) res++;
    25         if(root.left != null) res += pathNum(root.left, sum-root.val);
    26         if(root.right != null) res += pathNum(root.right, sum-root.val);
    27         
    28         return res;
    29     }
    30 }

     【java代码2】

     1 public class Solution {
     2     public int pathSum(TreeNode root, int sum) {
     3         HashMap<Integer, Integer> preSum = new HashMap<>();
     4         preSum.put(0, 1);
     5         return helper(root, 0, sum, preSum);
     6     }
     7     
     8     public int helper(TreeNode root, int curSum, int target, HashMap<Integer, Integer> preSum) {
     9         if(root == null) return 0;
    10         
    11         curSum += root.val;
    12         int res = preSum.getOrDefault(curSum-target, 0);
    13         //把当前节点加入到路径中
    14         preSum.put(curSum, preSum.getOrDefault(curSum, 0) + 1);
    15         //处理该节点的左子树和右子树
    16         res += helper(root.left, curSum, target, preSum);
    17         res += helper(root.right, curSum, target, preSum);
    18         //回溯。把已经处理完毕的当前节点从路径中清除
    19         preSum.put(curSum, preSum.get(curSum) - 1);
    20         
    21         return res;
    22     }
    23 }
  • 相关阅读:
    MongoDB Query 的几个方法
    jQuery日期和时间插件(jqueryuitimepickeraddon.js)中文破解版使用
    entity framework使用技巧
    SQL Server TSQL高级查询
    Visual Studio 2012资源管理器里单击打开改为双击打开文件
    ASP.NET MVC 3发布报错(ASP.NET MVC 3在没有安装环境的服务器上运行)的解决方案
    排序算法时间测试比较
    读书笔记之:C++ STL 开发技术导引3
    如何判断整数x的二进制中含有多少个1
    面试题:2012民生银行总行笔试题
  • 原文地址:https://www.cnblogs.com/liujinhong/p/6444322.html
Copyright © 2011-2022 走看看