題目連接:https://leetcode.com/problems/path-sum/description/ide
題目大意:給出一個二叉樹和一個數字,求出是否有從根節點到葉節點的路徑上的數之和等於這個數字,若是有返回true,不然返回false。spa
法一:利用先序遍歷的思想,先對結點值進行加和而後再遞歸計算左子樹和右子樹,注意一個細節是結點值有可能爲負值,因此在初始化的時候以及什麼時候進行判斷應特別注意,代碼以下(耗時1ms):code
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):
blog
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):遞歸
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 }
仍是沒明白爲啥非遞歸比遞歸要慢這麼多?難道是非遞歸寫錯了?ip