112.Path Sum
题目链接:https://leetcode.com/problems/path-sum/description/
题目大意:给出一个二叉树和一个数字,求出是否有从根节点到叶节点的路径上的数之和等于这个数字,如果有返回true,否则返回false。
法一:利用先序遍历的思想,先对结点值进行加和然后再递归计算左子树和右子树,注意一个细节是结点值有可能为负值,所以在初始化的时候以及何时进行判断应特别注意,代码如下(耗时1ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
法二(借鉴):后序非递归遍历,参见145题解,代码如下(耗时7ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
法三(借鉴):后序非递归遍历,参见145题解,代码如下(耗时9ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
还是没明白为啥非递归比递归要慢这么多?难道是非递归写错了?