Basic problems of binary tree in classic force deduction

Posted by Disgone on Fri, 28 Jan 2022 19:27:45 +0100

preface:

The vast majority of binary tree problems can be solved by recursion. Mastering the first, middle and last sequence traversal and sequence traversal of binary tree is the basis for quickly solving binary tree problems.

catalogue

preface:

Maximum depth of binary tree

Idea:

code:

Same tree

Idea:

code:

Symmetric binary tree

Idea:

code:

Judge balanced binary tree

Idea:

code:

Using preorder traversal and inorder traversal to generate binary tree

analysis:

code:

 

Maximum depth of binary tree

💡: Buckle link: Maximum depth of binary tree

Title: enter the root node of a binary tree and find the depth of the tree. The nodes (including root and leaf nodes) passing from root node to leaf node form a path of the tree, and the length of the longest path is the depth of the tree.

Idea:

After reviewing the question and knowing what is the maximum depth of a binary tree, we can know that the maximum depth of a binary tree should be the greater of the maximum depth of the left subtree and the maximum depth of the right subtree + 1

That is, the maximum depth of any subtree is equal to the maximum depth of its left subtree and the maximum depth of its right subtree + 1

This is obviously a recursive conclusion through which we can write code.

code:

    //Given a binary tree, returns the maximum depth of the binary tree
    class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
    //Recursive function
    //Recursive meaning: the maximum depth of the tree with node as the head
    public int process(TreeNode node) {
        //base case
        if (node == null) {
            return 0;
        }
        return Math.max(process(node.left), process(node.right)) + 1;
    }
    public int getMaxDepth(TreeNode root){
        return process(root);
    }

Same tree

💡: Force buckle link : same tree

Title:

Give you the root nodes p # and q of two binary trees, and write a function to check whether the two trees are the same.

If two trees are structurally identical and the nodes have the same value, they are considered to be the same.

Idea:

Classification discussion: there are only three situations for trees with p and q roots

(1) : P = = null & &q = = null two empty trees are naturally the same return true

(2)(p==null)^(q==null) one of the two trees is empty and the other is not empty. It must be different. return false

(3)p!=null&&q!=null

Return p.val = = q.val & & (the left subtree is the same) & & (the right subtree is the same)

code:

Through the above ideas, we can easily write code

    public class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
    public boolean isSame(TreeNode root1,TreeNode root2) {
        //There are three possibilities
        //1:root1==null&&root2==null
        //2:root1 and root2 have a null node
        //3:root1 and root2 are not empty
        if(root1==null^root2==null){
            return false;
        }

        if(root1==null&&root2==null){
            return true;
        }
        return root1.val== root2.val&&isSame(root1.left,root2.left)&&
                isSame(root1.right,root2.right);
    }

Symmetric binary tree

💡: Buckle link: Symmetric tree

Title: give you the root node of a binary tree # root and check whether it is axisymmetric.

Idea:

By analyzing the topic, we can get the following conclusions.

For any subtree, if its left subtree and right subtree are the same, then the subtree is a symmetric binary tree.

Here we use the strategy of the previous question to judge whether a binary tree is the same. By drawing on the ideas of the previous question, we can quickly write the code of this question.

code:

    //The idea of judging whether two binary trees are equal is the same
    //The left child on the left is equal to the right child on the right
    //The right child on the left is equal to the left child on the right
    public boolean isSymmetric(TreeNode node1,TreeNode node2){
        if((node1==null)^(node2==null)){
            return false;
        }
        if(node1==null&&node2==null){
            return true;
        }
        return node1.val==node2.val&&isSymmetric(node1.left,node2.right)&&
        isSymmetric(node1.right,node2.left);
    }
    public boolean isSymmetric(TreeNode root) {
        return isSymmetric(root,root);
    }

Judge balanced binary tree

💡: Buckle link: balanced binary tree

Title:

Given a binary tree, judge whether it is a highly balanced binary tree.

In this question, a highly balanced binary tree is defined as:

The absolute value of the height difference between the left and right subtrees of each node {of a binary tree shall not exceed 1.

Idea:

The definition of balanced binary tree is that the absolute value of the height difference between the left and right subtrees of any subtree is no more than 1

So the condition that any subtree is a balanced binary tree is

(1) : its left subtree is a balanced binary tree

(2) : its right subtree is a balanced binary tree

(3) : the height difference between the left subtree and the right subtree is no more than 1

By integrating the above ideas, we can write code quickly.

code:

    public class Info{
        public boolean isBalanced;
        public int height;
        public Info(boolean a,int b){
            isBalanced=a;
            height=b;
        }
    }
    public Info process(TreeNode node){
        if(node==null){
            return new Info(true,0);
        }
        //Left and right subtree for information
        Info leftInfo=process(node.left);
        Info rightInfo=process(node.right);
        //Integrate their own information
        int height=Math.max(leftInfo.height,rightInfo.height)+1;
        boolean isBalanced=false;
        if(leftInfo.isBalanced&&rightInfo.isBalanced&&
        (Math.abs(leftInfo.height-rightInfo.height)<2)){
            isBalanced=true;
        }
        return new Info(isBalanced,height);
    }
    public boolean isBalanced(TreeNode root) {
        return process(root).isBalanced;
    }

Using preorder traversal and inorder traversal to generate binary tree

💡: Buckle link: Using preorder traversal and inorder traversal to generate binary tree

Given two integer arrays , preorder and inorder, where , preorder is the preorder traversal of the binary tree and , inorder , is the inorder traversal of the same tree, please construct the binary tree and return its root node.

analysis:

First, we need to know the order of preorder traversal and inorder traversal.

1: preorder traversal: first process the header node, then traverse the left subtree, and then traverse the right subtree

2: middle order traversal: first traverse the left subtree, then process the head node, and then traverse the right subtree

The difficulty of this problem lies in how to write recursive functions, which requires solid recursive skills and coding ability.

Designing recursive parameters is the key point of writing recursive functions. Here we can think as follows:

We now have two arrays: a preorder array and a middle order array. We can write such recursive functions

Use pre [L1... R1] and in [L2... R2] to build a whole tree.

(1) : since the pre array is the processing order of the left and right headers, pre[L1] must be the header node of the whole tree, so we only need to

Distinguish the range of left subtree and right subtree in the pre array.

At this time, we need to consider the middle order array, because the middle order array is the order of the left and the right, so we only need to find the position of pre[L1] in in[L2...R2] as the find position, establish the left subtree in [L2... Find-1] and the right subtree in[find+1...R2] in the middle order array.

(2) : in this way, we can use recursion to establish left subtree and right subtree.

code:

    //Recursive function
    //The whole binary tree is established within the range of [L.. R] of preorder and inorder [L.. R]
    //Returns the head node of the entire binary tree
    //Speed up optimization: there is no need to traverse and find every time
    public TreeNode process(int[] preorder, int l, int r, int[] inorder, int L, int R,
    HashMap<Integer,Integer> map){
        //base case
        if(l>r){
            return null;
        }
        TreeNode head=new TreeNode(preorder[l]);
        if(l==r){
            return head;
        }
        int find=map.get(preorder[l]);
        head.left=process(preorder,l+1,l+find-L,inorder,L,find-1,map);
        head.right=process(preorder,r-(R-find)+1,r,inorder,find+1,R,map);
        return head;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder==null||inorder==null||preorder.length!=inorder.length){
            return null;
        }
        int N=preorder.length;
        //Prepare a hash table and record the subscripts corresponding to each value in the array
        HashMap<Integer,Integer> valueIndexMap=new HashMap<>();
        for(int i=0;i<N;i++){
            valueIndexMap.put(inorder[i],i);
        }
        return process(preorder,0,N-1,inorder,0,N-1,valueIndexMap);
    }

 

As my level is very limited, please let me know if you have any mistakes! If you can help, don't forget, thank you very much.

give the thumbs-up 👍 Collect ✨ Attention ✌

 

Topics: Java Algorithm leetcode Binary tree