leetcode-树

刷题笔记

常用方法

DFS

树的DFS遍历:利用stack
例子:

  • 题目104:Maximum Depth of Binary Tree
public int maxDepth(TreeNode root) {
    if(root == null) {
        return 0;
    }
    
    Stack<TreeNode> stack = new Stack<>();
    Stack<Integer> value = new Stack<>();
    stack.push(root);
    value.push(1);
    int max = 0;
    while(!stack.isEmpty()) {
        TreeNode node = stack.pop();
        int temp = value.pop();
        max = Math.max(temp, max);
        if(node.left != null) {
            stack.push(node.left);
            value.push(temp+1);
        }
        if(node.right != null) {
            stack.push(node.right);
            value.push(temp+1);
        }
    }
    return max;
}
  • 111:Minimum Depth of Binary Tree跟上面的几乎一致,但是将max换成了min
  • 关于优化解法—对于求最小而言,与最大不同,采用BFS能够更快的实现最终效果,而DFS则需要遍历所有的节点,因此对于Minmum而言,还是采用BFS会更好。

BFS

  • 树的BFS遍历:利用Queue
  • 104:
public int maxDepth(TreeNode root) {
    if(root == null) {
        return 0;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    int count = 0;
    while(!queue.isEmpty()) {
        int size = queue.size();
        while(size-- > 0) {
            TreeNode node = queue.poll();
            if(node.left != null) {
                queue.offer(node.left);
            }
            if(node.right != null) {
                queue.offer(node.right);
            }
        }
        count++;
    }
    return count;
}
  • 102 Binary Tree level Order:将树以层次表达出来,按照上面BFS做出适当修改即可(注意可以用size来表明每一行的node)
  • 199Binary Tree Right Side View:同样的层次化表示,只要先offer左边结点,就能够保证每一层的最右结点永远是最后一个poll的,利用这个特点将其加入结果当中即可。

与中序/后序/前序有关题目

  • 106 Construct Binary Tree from Inorder and Postorder Traversal
    这个题目的思路是比较简单的,只需要考虑自己人工转换的时候采取的思路即可,即把后序的最后一个当做根节点,同时划分中序,然后进行递归即可。问题在于初始想法为构造出新的inorder与postorder,无论是空间复杂度或者是可读性都很差。这里对于inorder和postorder都不做改变,但是用index来进行划分是一种更好的方法。
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        return buildTree(inorder,inorder.length-1,0,postorder,postorder.length-1);
    }
    private TreeNode buildTree(int[] inorder,int iS,int iE,int[] postorder,int pS){
        if(pS<0||iS<iE){return null;}
        
        
        TreeNode root =new TreeNode(postorder[pS]);
        int Rindex = iS;//找到根节点所在的位置从而进行划分
        for (int i = iS; i >= iE; i--) {
      if (inorder[i] == postorder[pS]) {
       Rindex = i;
       break;
  }
 }
        
 root.right = buildTree(inorder, iS, Rindex + 1, postorder, pS-1);
 root.left = buildTree(inorder, Rindex - 1, iE, postorder, pS - (iS - Rindex) -1);
 return root;
       

DP

DP的实际特性即为分解问题,此处做的题目还不够多,后续补充ing

  • 96:Unique Binary Search Trees 找到给定数目的node找二叉查找树的数目
    分析:每一个节点都可以作为头结点,则
    G[n]=T[1]+....T[n]G[n] =T[1]+....T[n]
    而对于给定头结点为i的二叉查找树,其实等于1~i-1构成的查找树的数目*i+1~n构成的数目
    则最终可以表示为如下格式
public int numTrees(int n) {
  int [] G = new int[n+1];
  G[0] = G[1] = 1;
    
  for(int i=2; i<=n; ++i) {
    for(int j=1; j<=i; ++j) {
      G[i] += G[j-1] * G[i-j];
    }
  }
  return G[n];
}
  • 95Unique Binary Search Trees II 给出所有的二叉查找树(不仅仅是数目)

Recursion

因为树的特性,很多题目都能够用递归来解决。重点在于分析问题能不能有分解到下一层次的特征。
比较典型的包括

  • 104Maximum Depth of Binary Tree(找到子树的最大depth递归即可)
  • 100 Same Tree
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null&&q!=null) return false;
        if(p==null||q==null) return true;
      
        if(p.val==q.val)
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
        else return false;    
        
    }
}

特殊解法

124 Binary Tree Max Path Sum

这个题目特殊的点在于设置了一个MAX的全局变量。主要思路为:对于每一个node,如果他是max path 上的node,那么存在两种情况,node为最高点,那么此时计算即为

Math.max(maxValue,left+right+node.val);

否则这个节点不是最高点,则一定是单边(最高节点为父节点),只能选择left/right 一边,否则矛盾。return后为recursion做准备

return Math.max(right+left)+node.val;

完整代码

public class Solution {
    int maxValue;
    
    public int maxPathSum(TreeNode root) {
        maxValue = Integer.MIN_VALUE;
        maxPathDown(root);
        return maxValue;
    }
    
    private int maxPathDown(TreeNode node) {
        if (node == null) return 0;
        int left = Math.max(0, maxPathDown(node.left));
        int right = Math.max(0, maxPathDown(node.right));
        maxValue = Math.max(maxValue, left + right + node.val);
        return Math.max(left, right) + node.val;
    }
}

95

99

注意事项/分析代办

  • 关于时空复杂度的问题
  • 关于JAVA 的一些语法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章