zoukankan      html  css  js  c++  java
  • 112.Path Sum

    题目链接:https://leetcode.com/problems/path-sum/description/

    题目大意:给出一个二叉树和一个数字,求出是否有从根节点到叶节点的路径上的数之和等于这个数字,如果有返回true,否则返回false。

    法一:利用先序遍历的思想,先对结点值进行加和然后再递归计算左子树和右子树,注意一个细节是结点值有可能为负值,所以在初始化的时候以及何时进行判断应特别注意,代码如下(耗时1ms):

     1     public boolean hasPathSum(TreeNode root, int sum) {
     2         if(root == null) {
     3             return false;
     4         }
     5         return dfs(root, sum, 0, false);
     6     }
     7     public static boolean dfs(TreeNode root, int sum, int cnt, boolean flag) {
     8         if(flag == true || root == null) {
     9             return flag;
    10         }
    11         cnt += root.val;
    12         if(cnt == sum && root.left == null && root.right == null) {
    13             //这个判断不能放在cnt加和之前
    14             //如果放在cnt之前,判断的是直到root的上一个结点的路径和情况,不是当前root结点的情况
    15             flag = true;
    16             return flag;
    17         }
    18         flag = dfs(root.left, sum, cnt, flag);
    19         flag = dfs(root.right, sum, cnt, flag);
    20         return flag;
    21     }
    View Code

    法二(借鉴):后序非递归遍历,参见145题解,代码如下(耗时7ms):

     1     public boolean hasPathSum(TreeNode root, int sum) {
     2         Stack<TreeNode> stack = new Stack<TreeNode>();
     3         if(root == null) {
     4             return false;
     5         }
     6         stack.push(root);
     7         TreeNode pre = null, cur = root.left;
     8         int cnt = root.val;
     9         while(!stack.isEmpty()) {
    10             while(cur != null) {
    11                 stack.push(cur);
    12                 cnt += cur.val;
    13                 cur = cur.left;
    14             }
    15             cur = stack.peek();
    16             if(cur.left == null && cur.right == null && cnt == sum) {
    17                 return true;
    18             }
    19             if(cur.right != null && pre != cur.right) {
    20                 cur = cur.right;
    21             }
    22             else {
    23                 cnt -= cur.val;
    24                 stack.pop();
    25                 pre = cur;
    26                 cur = null;
    27             }
    28         }
    29         return false;
    30     }
    View Code

    法三(借鉴):后序非递归遍历,参见145题解,代码如下(耗时9ms):

     1 public boolean hasPathSum(TreeNode root, int sum) {
     2         if(root == null) {
     3             return false;
     4         }
     5         Stack<TreeNode> stack = new Stack<TreeNode>();
     6         Stack<Integer> stackFlag = new Stack<Integer>();
     7         stack.push(root);
     8         stackFlag.push(0);
     9         TreeNode tmp = root.left;
    10         int cnt = root.val;
    11         while(!stack.isEmpty()) {
    12             while(tmp != null) {
    13                 cnt += tmp.val;
    14                 stack.push(tmp);
    15                 stackFlag.push(0);
    16                 tmp = tmp.left;
    17             }
    18             if(!stack.isEmpty()) {
    19                 if(stackFlag.peek() == 0) {
    20                     tmp = stack.peek().right;
    21                     stackFlag.pop();
    22                     stackFlag.push(1);
    23                 }
    24                 else {
    25                     if(cnt == sum && stack.peek().left == null && stack.peek().right == null) {
    26                         return true;
    27                     }
    28                     cnt -= stack.pop().val;
    29                     stackFlag.pop();
    30                 }
    31             }
    32         }
    33         return false;
    34     }
    View Code

    还是没明白为啥非递归比递归要慢这么多?难道是非递归写错了?

  • 相关阅读:
    老狼老狼几点了
    佐藤 Sato CL4NX 通过发送指令打印RFID标签
    HonyWell Intermec 通过Fingerprint指令打印RFID标签
    微信小程序中用echarts地图并点亮城市geo和effectScatter
    .NET Core
    数组去重
    Oracle
    CSS积累
    WebADNuke整理
    .net 基础面试题
  • 原文地址:https://www.cnblogs.com/cing/p/7778736.html
Copyright © 2011-2022 走看看