6.图 | 左程云算法笔记

142 阅读1分钟

判断一颗二叉树是否是搜索二叉树

public class Solution {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

//    判断一颗二叉树是否是搜索二叉树 中序遍历,一直升序就是,否则不是
    static int preValue = Integer.MIN_VALUE;
    public static boolean isBST(Node head) {
       if (head == null) return true;
       Boolean isLeftBST = isBST(head.left);
//       左子树不是搜索二叉树,则都不是
       if (!isLeftBST) return false;

       if (preValue >= head.value){
           return false;
       }else {
           preValue = head.value;
       }
       return isBST(head.right);
    }


//第二种方法 采用中序遍历的方式把全部节点都存储到队列里,再比对是否一直升序
    public static boolean isBST2(Node head) {
        if (head == null) {
            return true;
        }
        LinkedList<Node> inOrderList = new LinkedList<>();
        process(head, inOrderList);
        int pre = Integer.MIN_VALUE;
        for (Node cur : inOrderList) {
            if (pre >= cur.value) {
                return false;
            }
            pre = cur.value;
        }
        return true;
    }

    public static void process(Node node, LinkedList<Node> inOrderList) {
        if (node == null) {
            return;
        }
        process(node.left, inOrderList);
        inOrderList.add(node);
        process(node.right, inOrderList);
    }


}

判断一棵树是完全二叉树

public class Solution {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

//    如何判断一棵树是完全二叉树? 层序遍历
//    1.任一节点只有右孩子没有左孩子 false
//    2.在满足1的条件下,如果第一个遇到左右孩子节点不齐全的情况,之后所有的节点都必须是叶节点
    public static boolean isCBT(Node head) {
        if (head == null) {
            return true;
        }
        Queue<Node> queue = new LinkedList<>();
//        设置一个标志,在遇到第一个遇到左右孩子节点不齐全的情况后,设为true
        Boolean leaf = false;
        queue.add(head);
        while (!queue.isEmpty()){
            Node cur = queue.poll();
            if ((cur.right != null && cur.left == null) || (leaf && (cur.left != null || cur.right != null))) {
                return false;
            }
            if (cur.left != null) {
                queue.add(cur.left);
            }
            if (cur.right != null){
                queue.add(cur.right);
            }else {
                leaf = true;
            }
        }
        return true;
    }
}

判断一棵树是平衡二叉树

public class Solution {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

//    如何判断一棵树是平衡二叉树? 套路解题 左右子树高度差 <2
//    左子树需要某些信息 右子树需要某些信息 将这些信息封装成返回对象 判断情况
   public  class ReturnType{
       boolean isBalanced;
       int height;
       public ReturnType(boolean isB,int hei){
           isBalanced = isB;
           height = hei;
       }

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

    public ReturnType process(Node cur) {
        if(cur == null) {
            return new ReturnType(true,0);
        }

        ReturnType leftData = process(cur.left);
        ReturnType rightData = process(cur.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);
    }
    
}

判断一棵树是否是满二叉树

public class Solution {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

//    如何判断一棵树是满二叉树? 最大深度L 节点数N N== 2的L次方-1  等比数列求和公式
   public  class ReturnType{
       int nodes;
       int height;
       public ReturnType(int nod,int hei){
           nodes = nod;
           height = hei;
       }

   }
   public boolean isF(Node head) {
        if(head == null) {
            return true;
        }
        ReturnType returnType = process(head);
        return  returnType.nodes ==  (1 << returnType.height - 1);
   }

    public ReturnType process(Node cur) {
        if(cur == null) {
            return new ReturnType(0,0);
        }

        ReturnType leftData = process(cur.left);
        ReturnType rightData = process(cur.right);
        int height = Math.max(leftData.height, rightData.height) + 1;
        int nodes = leftData.nodes + rightData.nodes+ 1;
        return new ReturnType(nodes,height);
    }

}

二叉树最低公共祖先

public class Solution {

    public static class Node {
        public int value;
        public Node left;
        public Node right;
        public Node parent;

        public Node(int data) {
            this.value = data;
        }
    }

    /**
     * 在二叉树中找到一个节点的后继节点 中序遍历
     * 1.node有右树的时候,右树最左的节点
     * 2.node无右树的时候,往上是不是父亲的左孩子?是 -》 则父亲就是要找的后继节点
     *
     * */

    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 && node != 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;
    }
    
    // for test -- print tree
    public static void main(String[] args) {
        Node head = new Node(6);
        head.parent = null;
        head.left = new Node(3);
        head.left.parent = head;
        head.left.left = new Node(1);
        head.left.left.parent = head.left;
        head.left.left.right = new Node(2);
        head.left.left.right.parent = head.left.left;
        head.left.right = new Node(4);
        head.left.right.parent = head.left;
        head.left.right.right = new Node(5);
        head.left.right.right.parent = head.left.right;
        head.right = new Node(9);
        head.right.parent = head;
        head.right.left = new Node(8);
        head.right.left.parent = head.right;
        head.right.left.left = new Node(7);
        head.right.left.left.parent = head.right.left;
        head.right.right = new Node(10);
        head.right.right.parent = head.right;

        Node test = head.left.left;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.left.left.right;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.left;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.left.right;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.left.right.right;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.right.left.left;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.right.left;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.right;
        System.out.println(test.value + " next: " + getSuccessorNode(test).value);
        test = head.right.right; // 10's next is null
        System.out.println(test.value + " next: " + getSuccessorNode(test));
    }
}

折纸问题

请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。

此时折痕是凹下去的,即折痕突起的方向指向纸条的背面。

如果从纸条的下边向上方连续对折2次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。

给定一个输入参数N,代表纸条都从下边向上方连续对折N次。

请从上到下打印所有折痕的方向。

例如:N=1时,打印: down N=2时,打印: down down up

public class Solution {
    
//    中序遍历
    public static void printAllFolds(int N) {
        printProcess(1,N,true);
    }

    public static void printProcess(int i, int N, boolean down) {
        if (i > N) {
            return;
        }

        printProcess(i + 1,N,true);
        System.out.println(down == true ? "down" : "up");
        printProcess(i + 1,N,false);

    }

    public static void main(String[] args) {
        int N = 2;
        printAllFolds(N);
    }
}