112.Path Sum

題目連接: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     }
View Code

法二(借鑑):後序非遞歸遍歷,參見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     }
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

仍是沒明白爲啥非遞歸比遞歸要慢這麼多?難道是非遞歸寫錯了?ip

相關文章
相關標籤/搜索