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

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

posted on 2017-11-03 16:10  二十年后20  阅读(138)  评论(0编辑  收藏  举报

导航