LeetCode 662. Maximum Width of Binary Tree

时间:2022-06-13
本文章向大家介绍LeetCode 662. Maximum Width of Binary Tree,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

662. Maximum Width of Binary Tree

Given a binary tree, write a function to get the maximum width of the given tree. The width of a tree is the maximum width among all levels. The binary tree has the same structure as a full binary tree, but some nodes are null.

The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null nodes between the end-nodes are also counted into the length calculation.

Example 1:

Input: 

           1
         /   
        3     2
       /        
      5   3     9 

Output: 4
Explanation: The maximum width existing in the third level with the length 4 (5,3,null,9).

Example 2:

Input: 

          1
         /  
        3    
       /        
      5   3     

Output: 2
Explanation: The maximum width existing in the third level with the length 2 (5,3).

Example 3:

Input: 

          1
         / 
        3   2 
       /        
      5      

Output: 2
Explanation: The maximum width existing in the second level with the length 2 (3,2).

Example 4:

Input: 

          1
         / 
        3   2
       /       
      5       9 
     /         
    6           7
Output: 8
Explanation:The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7).

题目大意:求二叉树的宽度。

思路:二叉数的DFS,对二叉树的节点进行标号,若某节点的标号为m,那么左右孩子的标号为2*m、2*m+1。

解法一:

带返回值的

public int widthOfBinaryTree(TreeNode root) {
    List<Integer> lefts = new ArrayList<>();
    return dfs(root,1,0,lefts);
}

public int dfs(TreeNode root,int id,int depth,List<Integer> lefts){
    if (root == null ) return 0;
    if ( depth>=lefts.size()) lefts.add(id);
    return Math.max(id-lefts.get(depth)+1,Math.max(dfs(root.left,2*id,depth+1,lefts),dfs(root.right,2*id+1,depth+1,lefts)));
}

lefts记录的是最左节点的标号(id),每一个节点的id与最左节点的id相间就是宽度,取最大值就是结果。

解法二:

不带返回值的

错误解法:

public int widthOfBinaryTree(TreeNode root) {
    List<Integer> lefts = new ArrayList<>();
    Integer res = new Integer(0);
    dfs(root,1,0,lefts,res);
    return res;
}

public void dfs(TreeNode root,int id,int depth,List<Integer> lefts,Integer res ){
    if (root ==null) return;
    if (depth>=lefts.size()) lefts.add(id);
    res = Math.max(res,id+1-lefts.get(depth));
    dfs(root.left,id*2,depth+1,lefts,res);
    dfs(root.right,id*2+1,depth+1,lefts,res);
}

Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?

下面我们来看一个例子:

public class Test {
    public static void test1(Integer num){
        num = new Integer(5);
    }

    public static void test2(String str){
        str.replace("1", "4");
    }

    public static void main(String[] args) {
        Integer num = new Integer(1);
        test1(num);
        // 输出结果为1
        System.out.println(num.intValue());

        String str = new String("123");
        test2(str);
        // 输出结果为123
        System.out.println(str);
    }

}

上述程序很容易让人误以为String类型和包装类型是值传递。 其实我们认真想一下: String类型和包装类型都是对象类型,所以必然是引用传递;

但是由于String类和包装类都没有提供value对应的setter方法,我们无法改变其内容,所以导致我们看起来好像是值传递。所以说,String类和包装类是一种的特殊的引用传递。需要注意的是,这类特殊的引用传递不像普通的引用传递一样操作地址可以修改其值,因此上述的错误解法需要引起我们的注意。

那么我们也可以采用数组的方式作为参数,这样可以方便的解决。

正确的解法:

  public int widthOfBinaryTree(TreeNode root) {
        List<Integer> lefts = new ArrayList<>();
        int[] res= new int[1];
        dfs(root,1,0,lefts,res);
        return res[0];
    }

    public void dfs(TreeNode root,int id,int depth,List<Integer> lefts,int[] res ){
        if (root ==null) return;
        if (depth>=lefts.size()) lefts.add(id);
        res[0] = Math.max(res[0],id+1-lefts.get(depth));
        dfs(root.left,id*2,depth+1,lefts,res);
        dfs(root.right,id*2+1,depth+1,lefts,res);
    }

其实我们还可以将res设置为全局变量,这样少一个参数,但是往往我们设计程序的原则是少用全局变量。

总结,对二叉树的宽度问题求解时候,对节点进行编号往往可以达到事半功倍的效果。