B站左程云算法视频笔记06

如何判断一棵二叉树是否是搜索二叉树?

搜索二叉树的定义:一个节点,其左数的节点都比它小,右数的节点都比它大(一般没有重复的值)

思路:判断是否是搜索二叉树,可以采用中序遍历(左头右),看是否升序。

代码:递归/存入链表,判断是否升序

如何判断一棵二叉树是否是完全二叉树?

思路:1)任一节点,有右无左孩子,返回false 2)在1)成立的情况下下,如果遇到了第一个左右两个孩子不双全,后续节点是叶子节点

如何判断是否是满二叉树?

满二叉树(除了叶子节点外,所有节点都有两个子节点)的节点数N和最大深度L满足,N=2^L-1

如何判断是否是平衡二叉树?

平衡二叉树:任意节点的子树的高度差都小于1

判断平衡二叉树要知道 : 1)左子树是否是平衡二叉树 2)右子树是否是平衡二叉树 3)|左高 - 右高| 小于等于1

左子树返回的信息:是否是平衡二叉树、高度;右子树返回的信息:是否是平衡二叉树、高度

public static boolean isBalance(Node head){
    return process(head).isBalanced;
}

public static class ReturnType{
    public boolean isBalanced;
    public int height;

    public ReturnType(boolean isB, int hei){
        isBalanced = isB;
        height = hei;
    }
}

public static ReturnType process(Node x){
    if(x == null){//base 
        return new ReturnType(true, 0);
    }
    
    ReturnType leftData = process(x.left);
    ReturnType rightData = process(x.right);
    int height = Math.max(leftData.height, rightData.height) + 1;
    boolean isBalanced = leftData.isBalanced && rightData.isBalanced && Math.abs(leftData.height - rightData.height) < 2;
    return new ReturnType(isBalanced, height);
}

这是一类套路题,便于后续做树形DP

求解一个二叉树问题时,列可能性:假设在可以和左树要信息,和右树要信息的情况下

搜索二叉树:左树要是搜索二叉树,右树要是搜索二叉树 左max小于x,右min大于x

左数右树信息:是否是搜索二叉树,max,min(左树要求和右树要求求全集)

public static class ReturnData{
    public boolean isBST;
    public int min;
    public int max;
    public ReturnData(boolean is, int mi, inr ma){
       isBST = is;
        max = ma;
        min = mi;
} 
}
public static ReturnData process(Node x){
    if(x == null){
        return null;
    }
    ReturnData leftData = process(x.left);
    ReturnData rightData = process(x.right);
    
    int min = x.value;
    int max = x.value;
    if(leftData != null){
        min = Math.min(min, leftData.min);
        max = Math.max(max, leftData.max);
    }
    if(rightData != null){
        min = Math.min(min, rightData.min);
        max = Math.max(max, rightData.max);
    }
    
    boolean isBST = true;
    if(leftData != null && left.isBST || leftDAta.max >= x.value){
       isBst = false;
}
    if(rightData != null && right.isBST || rightData.min <= x.value){
       isBst = false;
}

    return new ReturnData(isBst,min,max);
}

是否是满二叉树

public static boolean isF(Node x){
    if(head == null){
        return true;
}
    Info data = process(head);
    return data.nodes == (1 << data.height -1);

}

public static class Info{
    public int height;
    public int nodes;

    public Info(int h ,int n){
        height = h;
        nodes = n;

}

    
}

public static Info process(Node x){
        if(x == null){
       return new Info(0,0);
}

        Info leftData = process(x.left);
        Info rightData = process(x.right);
        int height = Math.max(leftData.height,right.height)+1;
        int nodes = leftData.nodes + rightData.nodes + 1;

        return new Info(height, nodes);

}

最低公共祖先

//o1 o2 一定属于head为头的树
//返回o1 和 o2 公共祖先
public static Node lca(Node head ,Node o1, Node o2) {
        HashMap<Node,Node> fatherMap = new HashMap<>();
        fatherMap.put(head, head);
        process(head,fatherMap);
        HashSet<Node> set1 = new HashSet<>();
        ste.add(o1);
        Node cur = o1;
        while(cur != fatherMap.get(cur)){
            set1.add(cur);
            cur = fatherMap.get(cur);
}
        set1.add.head;

        while o2 set1

}

public static void process(Node head, HashMap<Node, Node> fatherMap) {
        if(head == null){
            return;
    }
       fatherMap.put(head.left, head);
       fatherMap.put(head.right,right);
       process(head.left,fatherMap);
       process(head.right,fatherMap)
}

后续节点

中序遍历中一个节点的下一个节点(线索二叉树)

分情况:x有右树,后继节点为右树上的最左节点;x无右树,往上走,看是不是父节点的左孩子

public static Node getSuccessorNode(Node node){
         if(node == null){
            return node;
    }
        if(node.right != null){
            return getLeftMost(node.right);
        }else{//无右子树
            Node parent = node.parent;
            while(parent != null && parent.left != node){//当前节点是其父节点的右孩子
                node = parent;
                parent = node.parent;
}   
            return parent; 
}

}

public static Node getLeftMost(Node node){
        if (node == null){
            return node;
    }
        while( node.left != null){
            node = node.left;
    }
        return node;
}

二叉树序列和反序列化(剑指offer)

//先序方式
public static String seriaByPre(Node node){
    if(head == null){
        return "#_";
    }
    String res = head.value + "_";
    res += serialByPre(head.left);
    res += serialByPre(head.right);
    return res;
} 

//反序列化
public static Node reconByPreString(String preStr){
    String[] values = preStr.split("_");
    Queue<String> queue = new LinkedList<String>();
    for(int i = 0; i != values.length; i++){
        queue.add(values[i]);
    } 
    return reconPreOrder(queue);
}

public static Node reconPreOrder(Queue<String> queue){
        String value = queue.poll();
        if(value.equals("#"){
        return null;
}
        Node head = new Node(Integer.valueOf(value));
        head.left = reconPreOrder(queue);
        head.right = reconPreOrder(queue);
        return head;
}

折纸问题

//递归过程
//i是节点的层数,N一共的层数,down == true凹 down ==false 凸
public static void printProcess(int i, int N, boolean down){
    if(i > N){
        return ;
    }
    printProcess(i+1,N,true);
    System.out.println(down ? "凹" :"凸");
    printProcess(i+1,N,false);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值