LeetCode 刷题笔记 (树)

1.  minimum-depth-of-binary-tree

题目描述

Given a binary tree, find its minimum depth.The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
求二叉树的最小深度;
 

解题思路

递归遍历二叉树的每一个节点:

(1)如果该节点为null,返回深度为0;

(2)如果节点不为空,返回左,右孩子中较小的那个孩子的深度+1;

注意:在(2)中容易出现的问题是,如果一个节点只有左孩子,没有右孩子,那么此时返回的应该是左孩子的深度,而不应该简单的认为返回两者的最小值;

1 public class Solution {
2     public int run(TreeNode root) {
3         if(root==null)
4             return 0;
5         int right = run(root.right);
6         int left = run(root.left);
7         return (left==0 || right==0)? (left+right+1) : Math.min(left,right)+1; 
8     }
9 }

2. binary-tree-postorder-traversal

题目描述

Given a binary tree, return the postorder traversal of its nodes' values. 后序遍历二叉树

For example:
Given binary tree{1,#,2,3},

   1
    \
     2
    /
   3

return[3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

解题思路:

后序遍历的顺序是:左->右->根,递归的方法很好写:

 1 public class Solution {
 2     ArrayList<Integer> list = new ArrayList<Integer>();
 3     public ArrayList<Integer> postorderTraversal(TreeNode root) {
 4         if(root==null)
 5             return list;
 6         if(root.left!=null)
 7             postorderTraversal(root.left);
 8         if(root.right!=null)
 9             postorderTraversal(root.right);
10         list.add(root.val);
11         return list;
12     }
13 }

非递归方法,使用栈来迭代:

要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
(1)如果P不存在左孩子和右孩子,则可以直接访问它;
(2)或者P存在孩子,但是其孩子都已被访问过了,则同样可以直接访问该结点
(3)若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了
注意:每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
 1 public class Solution {
 2     public ArrayList<Integer> postorderTraversal(TreeNode root) {
 3         ArrayList<Integer> list = new ArrayList<Integer>();
 4         if(root==null)
 5             return list;
 6         Stack<TreeNode> S = new Stack<TreeNode>();
 7         TreeNode preNode = null;
 8         S.push(root);
 9         while(!S.isEmpty()){
10             TreeNode curNode = S.peek();
11             if((curNode.left==null && curNode.right==null)||
12                (preNode != null && (preNode == curNode.left || preNode == curNode.right))){
13                 list.add(curNode.val);
14                 S.pop();
15                 preNode = curNode;
16             }
17             else{
18                 if(curNode.right!=null)
19                     S.push(curNode.right);
20                 if(curNode.left!=null)
21                     S.push(curNode.left);
22             }
23         }
24         return list;
25     }
26 }

3. binary-tree-preorder-traversal

题目描述

Given a binary tree, return the preorder traversal of its nodes' values. 非递归前序遍历二叉树

For example:
Given binary tree{1,#,2,3},

   1
    \
     2
    /
   3 

return[1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?

解题思路:

利用栈的结构,先序遍历的顺序为 根左右,根先进栈,每次从栈中弹出一个节点访问,并把它的孩子(不为空)按先右后左的顺序入栈,直到栈为空;
 1 public class Solution {
 2     public ArrayList<Integer> preorderTraversal(TreeNode root) {
 3         Stack<TreeNode> S = new Stack<TreeNode>();
 4         ArrayList<Integer> list = new ArrayList<Integer>();
 5         if(root==null){
 6             return list;
 7         }
 8         S.push(root);
 9         while(!S.isEmpty()){
10             TreeNode tmp = S.pop();
11             list.add(tmp.val);
12             if(tmp.right!=null)
13                 S.push(tmp.right);
14             if(tmp.left!=null)
15                 S.push(tmp.left);
16         }
17         return list;
18     }
19 }

4. sum-root-to-leaf-numbers

题目描述

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path1->2->3which represents the number123.

Find the total sum of all root-to-leaf numbers.

For example,

    1
   / \
  2   3

The root-to-leaf path1->2represents the number12.
The root-to-leaf path1->3represents the number13.

Return the sum = 12 + 13 =25.

从根节点到二叉树的叶子节点的每一条路径都有可以用一个数字表示,求这些数字的和;

解题思路:

递归来做,主要就是考虑递归条件和结束条件。递归条件即是把当前的sum乘以10并且加上当前节点传入下一函数,进行递归,最终把左右子树的总和相加。结束条件的话就是如果一个节点是叶子,那么我们应该累加到结果总和中,如果节点到了空节点,则不是叶子节点,不需要加入到结果中,直接返回0即可。本质是一次先序遍历

 1 public class Solution {
 2     public int sumNumbers(TreeNode root) {
 3         return Count(root, 0 );
 4     }
 5     static int Count(TreeNode root,int sum){
 6         if(root==null)
 7             return 0;
 8         if(root.left==null&&root.right==null)
 9             return sum*10+root.val;
10         return Count(root.left,sum*10+root.val)+Count(root.right,sum*10+root.val);
11     }
12 }

5. binary-tree-maximum-path-sum

题目描述

Given a binary tree, find the maximum path sum.

The path may start and end at any node in the tree.

For example:
Given the below binary tree,

       1
      / \
     2   3

Return 6.

 找到二叉树中和最大的一条路径(任意节点为起点,不是根节点,不重复,不相交)

解题思路:

从根节点出发,递归地去找每个节点的左右子树的最大和的路径,返回当前节点的值+左右子树中和较大的那个;

注意,遍历每一条可能的路径时,都要更新最大和是否小于当前这条路径的和,是则更新;

 1 public class Solution {
 2     public int sum = Integer.MIN_VALUE;
 3     public int maxPathSum(TreeNode root) {
 4         if(root==null)
 5             return 0;
 6         max(root);
 7         return sum;
 8     }
 9     public int max(TreeNode root){
10         if(root==null)
11             return 0;
12         int left = Math.max(0, max(root.left));
13         int right = Math.max(0, max(root.right));
14         sum = Math.max(sum, left+right+root.val);
15         return Math.max(left, right)+root.val;
16     }
17 }

猜你喜欢

转载自www.cnblogs.com/PJQOOO/p/10978662.html