Versão java da estrutura de dados da árvore binária (parte das perguntas da entrevista de oferta)

 Não olhe para o meu leopardo! olhar para baixo! ! !

contente

Primeiro, a operação básica da árvore binária

1. Obtenha o número de nós na árvore

2. Obtenha o número de nós folha

3. Ideia do subproblema - encontre o número de nós folha

4. Obtenha o número de nós na camada Kth

5. Obtenha a altura da árvore binária

6. Verifique se o elemento cujo valor é valor existe

7. Determine se uma árvore é uma árvore binária completa

Duas perguntas sobre oj relacionadas à árvore binária

1. Verifique se duas árvores são iguais

2. Uma subárvore de outra árvore

3. Profundidade máxima da árvore binária

4. Determine se uma árvore binária é uma árvore binária balanceada

5. Árvore Binária Simétrica

6. Construção e travessia da árvore binária

7. Percurso hierárquico da árvore binária

8. Dada uma árvore binária, encontre o ancestral comum mais próximo de dois nós especificados na árvore

9. Converta a árvore de busca de árvore binária em uma lista duplamente ligada ordenada

10. Construa uma árvore binária com base no percurso pré-ordem e no percurso inordenado de uma árvore

11. Construir uma árvore binária com base na travessia em ordem e na travessia em pós-ordem de uma árvore

12. Árvore binária para criar string

13. Implementação não recursiva de pré-ordem de árvore binária

14. Implementação transversal não recursiva em ordem de árvore binária


Primeiro, a operação básica da árvore binária

1. Obtenha o número de nós na árvore

Duas formas de pensar:

① Percorrendo a ideia:

   Defina uma contagem de contador, percorra a árvore binária, conte++ se houver nós; (o método de travessia aqui pode ser qualquer travessia pré-meio-pós-ordem escrita no blog no capítulo anterior)

O código é o seguinte: ! ! ! Observe que a contagem precisa ser definida fora desta função, caso contrário, seu valor de contagem retornará ao inicializador ao recuar

 int count=0;
    //以遍历的思路写
    int size1(BTNode root){
        if(root==null) {
            return 0;
        }else{
            count++;
             size1(root.left);
             size1(root.right);
        }
        return count;
    }

②Ideias de subquestões:

 código mostrar como abaixo:

    //以子问题思路写
    int size(BTNode root){
        if(root==null){
            return 0;
        }
       return  size(root.left)+size(root.right)+1;
    }

2. Obtenha o número de nós folha

Duas formas de pensar:

① Implementação transversal:

Código:

//以遍历的方式访问
    int count1=0;
    int getLeafNodeCount(BTNode root){
       // int count1=0;
        if(root==null){
            return 0;
        }else if(root.left==null && root.right==null){
            count1++;
        }
        getLeafNodeCount(root.left);
        getLeafNodeCount(root.right);
        return count1;
    }

②Ideias de subquestões:

código mostrar como abaixo:

int getLeafNodeCount(BTNode root){
        if(root==null){
            return 0;
        }else if(root.left==null && root.right==null){
            return 1;
        }
        return getLeafNodeCount(root.left)+getLeafNodeCount(root.right);
    }
}

3. Ideia do subproblema - encontre o número de nós folha

     Esta questão foi obtida na segunda ideia em 2

4. Obtenha o número de nós na camada Kth

 Ideias para resolução de problemas:

código mostrar como abaixo:

//求第K层结点的个数
 public int getKLevelNodeCount(int k){
    return getKLevelNodeCount(root, k);
    }
     // 获取第K层结点的个数
    private int getKLevelNodeCount(BTNode root,int k){
          if(root==null || k<=0){
             return 0;
          }
          if(k==1){
              return 1;
          }
          return getKLevelNodeCount(root.left, k-1)+getKLevelNodeCount(root.right, k-1);

    }

5. Obtenha a altura da árvore binária

Análise do pensamento:

código mostrar como abaixo:

 // 获取二叉树的高度(时间复杂度为O(n))
    int getHeight(BTNode root){
        if(root==null){
            return 0;
        }
       int leftHeight=getHeight(root.left);
        int rightHeight=getHeight(root.right);
//此处用的是三目运算符求取两者中的较大值
        return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
    }

6. Verifique se o elemento cujo valor é valor existe

Ideias para resolução de problemas:

código mostrar como abaixo:

// 检测值为value的元素是否存在
    boolean find(BTNode root, int val) {
        if (root == null) {
            return false;
        } else if (root.val == val) {
            return true;
        }
        if (find(root.left, val) || find(root.right, val)) {
            return true;
        }
        return false;
    }

7. Determine se uma árvore é uma árvore binária completa

Ideias para resolução de problemas:

código mostrar como abaixo:

  boolean isCompleteTree(BTNode root){
        if(root == null) return true;
        Queue<BTNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            BTNode cur = queue.poll();
            if(cur != null) {
                queue.offer(cur.left);
                queue.offer(cur.right);
            }else {
                break;
            }
        }
//第二个while循环实质上就是在cur=null的基础上来判断实现的,若是整个为空即null 则true;反之为false
        while (!queue.isEmpty()) {
            BTNode top = queue.peek();
            if(top != null) {
                return false;
            }
            queue.poll();
        }
        return true;
    }

1. Verifique se duas árvores são iguais

100. A mesma árvore - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/same-tree/

Ideias para resolução de problemas:

   Para saber se duas árvores são iguais: 

   ①A estrutura dos números é a mesma

   ②O valor correspondente ao nó na posição correspondente é o mesmo

código mostrar como abaixo:

 public boolean isSameTree(TreeNode p, TreeNode q ){
        if(p == null && q != null || p != null && q == null) {
            return false;
        }
        if(p == null && q == null) {
            return true;
        }
        if(p.val != q.val) {
            return false;
        }
        //p != null && q!= null && p.val == q.val
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }

2. Uma subárvore de outra árvore

572. Subárvore de outra árvore - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/subtree-of-another-tree/

código mostrar como abaixo:

 public boolean isSubtree(TreeNode root, TreeNode subRoot) {
  if(root == null || subRoot == null) {
             return false;
         }
        //根节点和subroot是不是两颗相同的树
        if(isSameTree(root,subRoot)) {
            return true;
        }
        //subRoot是不是root的左子树
        if(isSubtree(root.left,subRoot)) {
            return true;
        }
        if(isSubtree(root.right,subRoot)) {
            return true;
        }
        return false;
}
}

3. Profundidade máxima da árvore binária

104. Profundidade máxima da árvore binária - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

 5 perguntas sobre o funcionamento básico da mesma árvore binária, consulte o topo deste blog

4. Determine se uma árvore binária é uma árvore binária balanceada

110. Árvore Binária Balanceada - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/balanced-binary-tree/submissions/

Ideias para resolução de problemas: 

class Solution {
   public int height (TreeNode root) {
        if(root == null) {return 0;}
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        return (leftHeight > rightHeight) ?
                (leftHeight+1) :(rightHeight+1);
    }

    /**
     时间复杂度:O(N^2)
     */
    public boolean isBalanced(TreeNode root) {
        if(root == null) return true;
        int left = height(root.left);
        int right = height(root.right);
        return Math.abs(left-right) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }
}

5. Árvore Binária Simétrica

101. Árvore Binária Simétrica - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/symmetric-tree/Ideias de solução :

código mostrar como abaixo:

class Solution {
     public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return isSymmetricChild(root.left,root.right);
    }
   public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
       //第一种情况
       if(leftTree == null && rightTree == null) return true;
       //第二种情况
        if((leftTree == null && rightTree != null)||(leftTree != null && rightTree == null))               return false;
        //第三种情况
        if(leftTree.val != rightTree.val) return false;
        return isSymmetricChild(leftTree.left,rightTree.right) &&
                isSymmetricChild(leftTree.right,rightTree.left);
    }

6. Construção e travessia da árvore bináriaicon-default.png?t=M0H8

7. Percurso hierárquico da árvore binária

102. Percurso de ordem de nível da árvore binária - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

Ideias para resolução de problemas:

imprimir travessia hierárquica com a ajuda de uma fila e uma variável temporária cur

① Discuta se a raiz está vazia ou não

②Quando a fila não estiver vazia, retire o elemento final da fila para cur e imprima-o através de cur.val

③A situação das subárvores esquerda e direita é discutida em um loop, então use while para fazer um loop

Dois tipos de códigos:

①Código comum:

  //打印层序遍历二叉树
  public void levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
//①判断树是否为空的情况
        if(root == null) return;
        queue.offer(root);
//②判断队列是否为空
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            System.out.print(cur.val+" ");
            if(cur.left != null) {
                queue.offer(cur.left);
            }
            if(cur.right != null) {
                queue.offer(cur.right);
            }
        }
    }

②O código para resolver o problema no JO:

Ideias para resolução de problemas: 

código mostrar como abaixo:

//层序遍历访问打印元素
List<List<Integer>> ret = new ArrayList<>();
        if(root == null) return ret;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
//当前的结点个数size
            int size = queue.size();
            List<Integer> list = new ArrayList<>();
            while (size != 0) {
                TreeNode cur = queue.poll();
//将同层结点放在一个list中
                list.add(cur.val); 
                if(cur.left != null) {
                    queue.offer(cur.left);
                }
                if(cur.right != null) {
                    queue.offer(cur.right);
                }
                size--;//1 0
            }
//将所有一层link的结点放在同一个list中
            ret.add(list);
        }
//最后返回整个所需的ret
        return ret;
}

8. Dada uma árvore binária, encontre o ancestral comum mais próximo de dois nós especificados na árvore

236. O ancestral comum mais próximo da árvore binária - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

Ideias para resolução de problemas:

Ideia 1 : Um método de projetar uma árvore binária a partir da ideia de uma árvore de busca binária

Se uma árvore de busca binária

Ideias detalhadas:

1. root==p || root==q (p, q é um nó)
O ancestral comum mais próximo neste momento é a raiz
2. Pode estar à esquerda ou à direita da raiz
① p.val<root.val && q.val< root.val (p, q estão ambos na subárvore esquerda da raiz) o
ancestral comum mais próximo está na subárvore esquerda


②p.val>root.val && q.val>root.val (p, q estão ambos na subárvore direita da raiz)
O ancestral comum mais próximo está na subárvore direita


3. O ancestral comum mais próximo é a raiz
①p.val>root.val && q.val<root.val (p está na subárvore esquerda, q está na subárvore direita)
②p.val<root.val && q.val> root.val (p está na subárvore direita, q está na subárvore esquerda)


 código mostrar como abaixo:

//二叉树的最近公共祖先
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null){
            return null;
        }if(root==p||root==q){
            return root;
        }
        TreeNode l=lowestCommonAncestor(root.left,p,q);
        TreeNode r=lowestCommonAncestor(root.right,p,q);
       if(l!=null && r!=null){
    return root;
}else if(l!=null){
    return l;
}else{
    return r;
}
        }
    }

 Pensamento ② :

Obtido da representação parental da criança 

código mostrar como abaixo:

class Solution {
    //root:
    public boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode>stack){
if(root==null || node==null){
return false;
}stack.push(root);
if(root==node){
    return true;
}
boolean flg=getPath(root.left,node,stack);
if(flg==true){
    return true;
}
 flg=getPath(root.right,node,stack);
 if(flg==true){
     return true;
 }
stack.pop();
return false;
    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null){
            return null;
        }
        Stack<TreeNode> stack1=new Stack<>();
        getPath(root,p,stack1);
        Stack<TreeNode> stack2=new Stack<>();
        getPath(root,q,stack2);
        int size1=stack1.size();
        int size2=stack2.size();
        if(size1>size2){
            int size=size1-size2;
            while(size!=0){
            stack1.pop();
            size--;
            }
            while(!stack1.isEmpty() && !stack2.isEmpty()){
                //用等号判断地址
                if(stack1.peek()==stack2.peek()){
                    return stack1.pop();
                }else{
                    stack1.pop();
                    stack2.pop();
                }
            }
            }else{
                 int size=size2-size1;
            while(size!=0){
            stack2.pop();
            size--;
            }
            while(!stack1.isEmpty() && !stack2.isEmpty()){
                //用等号判断地址
                if(stack1.peek()==stack2.peek()){
                    return stack1.pop();
                }else{
                    stack1.pop();
                    stack2.pop();
                }
            }
            }
            return null;
        }
    }

9. Converta a árvore de busca de árvore binária em uma lista duplamente ligada ordenada

link Niuke.com https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking ideias para solução de problemas:

As características da árvore de busca binária foram introduzidas antes (por isso sabe-se que a árvore de busca binária é ordenada quando percorrida em ordem)

①Inorder travessia desta árvore binária

② Lista duplamente ligada

 código mostrar como abaixo:

public class Solution {
    //先写出一个中序遍历
    TreeNode prev=null;
    public void inOrder(TreeNode pCur){
        if(pCur==null)return ;
        inOrder(pCur.left);
        pCur.left=prev;
        if(prev!=null){
              prev.right=pCur;
        }
      prev=pCur;
          inOrder(pCur.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        inOrder(pRootOfTree);
        TreeNode head=pRootOfTree;
        while(head.left!=null){
            head=head.left;
        }
        return head;
    }
}

10. Construa uma árvore binária com base no percurso pré-ordem e no percurso inordenado de uma árvore

105. Construir árvore binária a partir da sequência de travessia pré-ordem e in-ordem - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

Ideias para resolução de problemas:

①Encontre o nó raiz

② Encontre as subárvores esquerda e direita através do percurso em ordem

③ Crie subárvores esquerda e direita respectivamente

código mostrar como abaixo:

class Solution {
//将preIndex设置为全局变量用来保证在递归的过程中当子树根结点返回到总根后的空指针异常
    public int preIndex=0;
    public TreeNode createTreeByPandI(int[]preorder,int[]inorder,int inbegin,int inend){
        if(inbegin>inend){
            //左树或者右树为空
            return null;
        }
        TreeNode root=new TreeNode(preorder[preIndex]);
        int rootIndex=findIndexOfI(inorder,inbegin,inend,preorder[preIndex]);
            if(rootIndex==-1){
                return null;
            }
            preIndex++;
            root.left=createTreeByPandI(preorder,inorder,inbegin,rootIndex-1);
            root.right=createTreeByPandI(preorder,inorder,rootIndex+1,inend);
            return root;
        }
    private int findIndexOfI(int[]inorder,int inbegin,int inend,int key){
        for(int i=inbegin;i<=inend;i++){
            if(inorder[i]==key){
                return i;
            }
        }
return -1;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder==null||inorder==null){
    return null;
}return createTreeByPandI(preorder,inorder,0,inorder.length-1);
    }
}

11. Construir uma árvore binária com base na travessia em ordem e na travessia em pós-ordem de uma árvore

106. Construir árvore binária a partir da sequência de travessia inorder e pós-ordem - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder- traversal/ problem- Resolvendo ideias:

Diferenças da pergunta anterior:

①postIndex está na extrema direita (ou seja, se o nó raiz for percorrido em pós-ordem, ele será percorrido um após o outro)

② Visite a árvore direita primeiro e depois a árvore esquerda

código mostrar como abaixo:

class Solution {
 public int postIndex=0;
    public TreeNode createTreeByPandI(int[]inorder,int[]postorder,int inbegin,int inend){
        if(inbegin>inend){
            //左树或者右树为空
            return null;
        }
        TreeNode root=new TreeNode(postorder[postIndex]);
        int rootIndex=findIndexOfI(inorder,inbegin,inend,postorder[postIndex]);
            if(rootIndex==-1){
                return null;
            }
            postIndex--;
            //分别创建右子树和左子树
            root.right=createTreeByPandI(inorder,postorder,rootIndex+1,inend);
            root.left=createTreeByPandI(inorder,postorder,inbegin,rootIndex-1);
            return root;
        }
    private int findIndexOfI(int[]inorder,int inbegin,int inend,int key){
        for(int i=inbegin;i<=inend;i++){
            if(inorder[i]==key){
                return i;
            }
        }
return -1;
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        postIndex=postorder.length-1;
if(postorder==null||inorder==null){
    return null;
}return createTreeByPandI(inorder,postorder,0,inorder.length-1);
    }
}

 12. Árvore binária para criar string

606. Crie uma string baseada em árvore binária - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/construct-string-from-binary-tree/Problem-solving
ideas:

 código mostrar como abaixo:

class Solution {
  public void treeToString(TreeNode t,StringBuilder sb) {
        if(t == null) return;
        sb.append(t.val);
        if(t.left != null) {
            sb.append("(");
            treeToString(t.left,sb);
            sb.append(")");
        }else {
            //t.left == null
            if(t.right == null) {
                return;
            }else{
                sb.append("()");
            }
        }

        if(t.right == null) {
            return;
        }else{
            sb.append("(");
            treeToString(t.right,sb);
            sb.append(")");
        }
    }
    public String tree2str(TreeNode root) {
        if(root == null) return null;
        StringBuilder sb = new StringBuilder();
        treeToString(root,sb);
        return sb.toString();
    }
}

13. Implementação não recursiva de pré-ordem de árvore binária

144. Pré-encomenda Traversal da Árvore Binária - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/binary-tree-preorder-traversal/submissions/

Ideias para resolução de problemas:

código mostrar como abaixo:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer>ret=new ArrayList<>();
        Stack<TreeNode>stack=new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                ret.add(cur.val);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.print(top.val+" ");
            cur = top.right;
        }
        return ret;
    }

14. Implementação transversal não recursiva em ordem de árvore binária

94. Inorder Traversal of Binary Tree - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

Ideia de solução de problemas: a mesma implementação de travessia não recursiva de pré-ordem de 13

código mostrar como abaixo:

class Solution {
 public List<Integer> inorderTraversal(TreeNode root) {
            List<Integer> ret= new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            TreeNode cur = root;
            while (cur != null || !stack.isEmpty()) {
                if (cur != null) {
                    stack.push(cur);
                    cur = cur.left;
                } else {
                    cur = stack.pop();
                    ret.add(cur.val);
                    cur = cur.right;
                }
            }
            return ret;
        }
    }

Acho que você gosta

Origin blog.csdn.net/weixin_58850105/article/details/122564501
Recomendado
Clasificación