Depois de trabalhar duro por tantos anos, olhando para trás, quase tudo são longos contratempos e sofrimentos. Para a vida da maioria das pessoas, navegar tranquilamente é apenas ocasional, e frustração, insuportável, ansiedade e confusão são o tema principal. Subimos ao palco que não escolhemos, interpretamos o roteiro que não escolhemos. Continue!
Índice
1. Traversal de pré-ordem da árvore binária
2. Traversal inorder de uma árvore binária
3. Percurso pós-ordem da árvore binária
4. Encontre a travessia da ordem de nível da árvore binária
5. Imprima a árvore binária em ordem de zigue-zague
6. A profundidade máxima da árvore binária
7. O caminho que soma a um determinado valor na árvore binária (1)
8. Árvore de busca binária e lista duplamente encadeada
11. Imagem espelhada da árvore binária
12. Determine se é uma árvore de pesquisa binária
13. Determine se é uma árvore binária completa
14. Determine se é uma árvore binária balanceada
15. O ancestral comum mais próximo da árvore de busca binária
16. Encontre o ancestral comum mais próximo de dois nós em uma árvore binária
17. Reconstrua a árvore binária
1. Traversal de pré-ordem da árvore binária
Link do tópico: Traversal de pré-encomenda da árvore binária
Ideia: chame a função de travessia de pré-ordem para armazenar o resultado na coleção e, em seguida, passe-a para a matriz e travessia de pré-ordem: nó raiz, subárvore esquerda, subárvore direita.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public void preOrder(TreeNode root, List<Integer> lst){
if(root == null){
return ;
}
lst.add(root.val) ;
preOrder(root.left, lst) ;
preOrder(root.right, lst) ;
}
public int[] preorderTraversal (TreeNode root) {
// write code here
List<Integer> lst = new ArrayList<>() ;
preOrder(root, lst) ;
int [] ans = new int [lst.size()] ;
int i = 0;
for(int num : lst){
ans[i++] = num ;
}
return ans ;
}
}
2. Traversal inorder de uma árvore binária
Link do tópico: Traversal inorder de uma árvore binária_Niuke题霸_Niuke.com
Ideia: Igual à ideia de pré-encomenda, exceto que a subárvore esquerda é a primeira, depois o nó raiz e, finalmente, a subárvore direita.
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public int[] inorderTraversal (TreeNode root) {
// write code here
List<Integer> lst = new ArrayList<>() ;
inOrder(root, lst) ;
int i = 0 ;
int [] ans = new int [lst.size()] ;
for(int num : lst){
ans[i++] = num ;
}
return ans ;
}
public void inOrder(TreeNode root, List<Integer> lst){
if(root == null){
return ;
}
inOrder(root.left, lst) ;
lst.add(root.val) ;
inOrder(root.right, lst) ;
}
}
3. Percurso pós-ordem da árvore binária
Link do tópico: Percurso pós-ordem de uma árvore binária_Niuke题霸_Niuke.com
Ideia: Primeiro a subárvore esquerda, depois a subárvore direita e finalmente o nó raiz.
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public int[] postorderTraversal (TreeNode root) {
// write code here
List<Integer> lst = new ArrayList<>() ;
postOrder(root, lst) ;
int i = 0 ;
int [] ans = new int [lst.size()] ;
for(int num : lst){
ans[i++] = num ;
}
return ans ;
}
public void postOrder(TreeNode root, List<Integer> arraylist){
if(root == null){
return ;
}
postOrder(root.left,arraylist) ;
postOrder(root.right,arraylist) ;
arraylist.add(root.val) ;
}
}
4. Encontre a travessia da ordem de nível da árvore binária
Link do tópico: Encontrando a travessia da ordem de nível de uma árvore binária
Ideia: Baseando-se no recurso primeiro a entrar, primeiro a sair da fila, todos os elementos de cada camada são retirados da fila e armazenados na coleção, e todos os elementos da próxima camada são enfileirados.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
// write code here
ArrayList<ArrayList<Integer>> lst = new ArrayList<>() ;
Queue<TreeNode> queue = new LinkedList<>() ;
if(root == null){
return lst ;
}
queue.add(root) ;
while(!queue.isEmpty()){
int s = queue.size() ;
ArrayList<Integer> list = new ArrayList<>() ;
for(int i=0; i<s; i++){
TreeNode node = queue.poll() ;
list.add(node.val) ;
if(node.left != null){
queue.offer(node.left) ;
}
if(node.right != null){
queue.offer(node.right) ;
}
}
lst.add(list) ;
}
return lst ;
}
}
5. Imprima a árvore binária em ordem de zigue-zague
Link do tópico: Imprimir árvore binária em ordem de zigue-zague
Idéia: Com a ajuda de filas, cada camada entra na fila, e todas são desenfileiradas na coleção.Se for uma camada par, os elementos da coleção são invertidos.
Versão Java:
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> lst = new ArrayList<>() ;
Queue<TreeNode> queue = new LinkedList<>() ;
if(pRoot == null){
return lst ;
}
queue.offer(pRoot) ;
int level = 1 ;
while(!queue.isEmpty()){
int size = queue.size() ;
ArrayList<Integer> list = new ArrayList<>() ;
for(int i=0; i<size; i++){
TreeNode node = queue.poll() ;
list.add(node.val) ;
if(node.left !=null){
queue.add(node.left) ;
}
if(node.right != null){
queue.add(node.right) ;
}
}
if(level%2==0){
Collections.reverse(list) ;
}
level ++ ;
lst.add(list) ;
}
return lst ;
}
}
6. A profundidade máxima da árvore binária
Link do tópico: A profundidade máxima de uma árvore binária
Ideia: Com a ajuda de filas, travessia de camadas, cada camada entra na fila, registra o número de camadas e sai da fila.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型
*/
public int maxDepth (TreeNode root) {
// write code here
Queue<TreeNode> queue = new LinkedList<>();
if(root == null){
return 0 ;
}
int level = 0;
queue.offer(root) ;
while(!queue.isEmpty()){
level ++ ;
int size = queue.size() ;
for(int i=0; i<size; i++){
TreeNode node = queue.poll() ;
if(node.left != null){
queue.offer(node.left) ;
}
if(node.right != null){
queue.offer(node.right) ;
}
}
}
return level ;
}
}
7. O caminho que soma a um determinado valor na árvore binária (1)
Link do tópico: O caminho de um determinado valor em uma árvore binária (1)
Ideia: Implementação recursiva, cada vez percorre recursivamente as subárvores esquerda e direita e acumula o valor do nó atual, se a condição for atendida, retorna verdadeiro
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param sum int整型
* @return bool布尔型
*/
public boolean hasPathSum (TreeNode root, int sum) {
// write code here
if(root == null){
return false ;
}
int s = 0 ;
return preOrder(root, sum, s) ;
}
public boolean preOrder(TreeNode root, int sum, int s){
if(root == null){
return false ;
}
s += root.val ;
if(root.left == null && root.right == null && s==sum){
return true ;
}
return preOrder(root.left, sum, s) || preOrder(root.right, sum, s) ;
}
}
8. Árvore de busca binária e lista duplamente encadeada
Link para o tópico: Árvore de pesquisa binária e lista duplamente encadeada
Versão Java:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
TreeNode root = null ;
TreeNode pre = null ;
public TreeNode Convert(TreeNode pRootOfTree) {
//二叉搜索树,也是二叉排序树,左子树小于根节点,右子树大于根节点
//如果中序遍历,则可以由小到大获取元素
if(pRootOfTree == null){
return null ;
}
Convert(pRootOfTree.left) ;
if(pre == null){
pre = pRootOfTree ;
root = pre ;
}else{
//修改双向指针,并更新当前节点为前驱节点
pre.right = pRootOfTree ;
pRootOfTree.left = pre ;
pre = pRootOfTree ;
}
Convert(pRootOfTree.right) ;
return root ;
}
}
9. Árvore binária simétrica
Link do Tópico: Árvore Binária Simétrica_Niuke Topic_Niuke.com
Ideia: julgue iterativamente se a subárvore esquerda e a subárvore direita das duas árvores são consistentes.
Versão Java:
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
boolean isSymmetrical(TreeNode pRoot) {
return f(pRoot, pRoot) ;
}
boolean f(TreeNode root1, TreeNode root2){
if(root1==null && root2 == null){
return true ;
}
if(root1 == null || root2 == null){
return false ;
}
if(root1.val != root2.val){
return false ;
}
return f(root1.left, root2.right) && f(root1.right, root2.left) ;
}
}
10. Mesclar árvores binárias
Link do Tópico: Mesclando Árvores Binárias_Niuke Topic_Niuke.com
Ideia: Mesclar a árvore binária recursivamente, mesclá-la na subárvore esquerda e, finalmente, retornar a subárvore esquerda.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param t1 TreeNode类
* @param t2 TreeNode类
* @return TreeNode类
*/
public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
// write code here
if(t1 == null){
return t2 ;
}
if(t2 == null){
return t1 ;
}
t1.val = t1.val + t2.val ;
if(t2.left != null){
t1.left = mergeTrees(t1.left, t2.left) ;
}
if(t2.right != null){
t1.right = mergeTrees(t1.right, t2.right) ;
}
return t1 ;
}
}
11. Imagem espelhada da árvore binária
Link do tópico: Imagem espelhada da árvore binária_Niuke题霸_Niuke.com
Idéia: Atravesse recursivamente as subárvores esquerda e direita, apenas troque as subárvores esquerda e direita a cada vez.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return TreeNode类
*/
public TreeNode Mirror (TreeNode pRoot) {
// write code here
if(pRoot == null){
return null ;
}
TreeNode tmp = pRoot.left ;
tmp = pRoot.left ;
pRoot.left = pRoot.right ;
pRoot.right = tmp ;
Mirror(pRoot.left) ;
Mirror(pRoot.right) ;
return pRoot ;
}
}
12. Determine se é uma árvore de pesquisa binária
Link do tópico: Julgando se é uma árvore de pesquisa binária
Ideia: travessia em ordem, armazene o valor e, em seguida, julgue se os elementos aumentam por sua vez.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
public boolean isValidBST (TreeNode root) {
// write code here
ArrayList<Integer> list = new ArrayList<>() ;
inOrder(root, list) ;
for(int i=1; i<list.size(); i++){
if(list.get(i-1) >= list.get(i)){
return false ;
}
}
return true ;
}
public void inOrder(TreeNode root, ArrayList<Integer> list){
if(root == null){
return ;
}
inOrder(root.left, list) ;
list.add(root.val) ;
inOrder(root.right, list) ;
}
}
13. Determine se é uma árvore binária completa
Link do tópico: Julgando se é uma árvore binária completa
Ideia: De acordo com o princípio da fila, primeiro a entrar, primeiro a sair, se o nó atual estiver vazio, todos os nós subseqüentes devem estar vazios.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
public boolean isCompleteTree (TreeNode root) {
// write code here
//当前节点为空,后面的节点必须全为空
Queue<TreeNode> queue = new LinkedList<>() ;
if(root == null){
return true ;
}
queue.add(root) ;
boolean flag = false ;
while(!queue.isEmpty()){
TreeNode node = queue.poll() ;
if(node == null){
flag = true ;
}else{
if(flag){
return false ;
}
queue.add(node.left) ;
queue.add(node.right) ;
}
}
return true ;
}
}
14. Determine se é uma árvore binária balanceada
Link do tópico: Julgando se uma árvore binária é balanceada
Ideia: Calcule a profundidade da árvore binária e julgue se a diferença entre as profundidades das subárvores esquerda e direita é maior que 1.
Versão Java:
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root == null){
return true ;
}
int left = depth(root.left) ;
int right = depth(root.right) ;
if(Math.abs(left - right) > 1){
return false ;
}
return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right) ;
}
public int depth(TreeNode root){
if(root == null){
return 0 ;
}
int left = depth(root.left) ;
int right = depth(root.right) ;
return Math.max(left, right) + 1 ;
}
}
15. O ancestral comum mais próximo da árvore de busca binária
Link do tópico: o ancestral comum mais próximo de uma árvore de pesquisa binária
Ideia: A árvore de busca binária satisfaz a natureza ordenada da travessia inorder, travessia recursiva e encontra o ancestral comum mais próximo.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param p int整型
* @param q int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int p, int q) {
// write code here
return find(root, p, q).val ;
}
public TreeNode find(TreeNode root, int p, int q) {
if ((p <= root.val && q >= root.val) || (p >= root.val && q <= root.val)) {
return root ;
} else if (p <= root.val && q <= root.val) {
return find(root.left, p, q) ;
}else{
return find(root.right, p, q) ;
}
}
}
16. Encontre o ancestral comum mais próximo de dois nós em uma árvore binária
Link do tópico: Encontre o ancestral comum mais próximo de dois nós em uma árvore binária
Ideia: Pesquise recursivamente nas subárvores esquerda e direita sucessivamente, retorne se encontrado e retorne ao nó raiz se não for encontrado.
Versão Java:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
return find(root, o1, o2).val ;
}
public TreeNode find(TreeNode root, int o1, int o2) {
if (root == null || root.val == o1 || root.val == o2) {
return root ;
}
TreeNode left = find(root.left, o1, o2) ;
TreeNode right = find(root.right, o1, o2) ;
if(left == null){
return right ;
}
if(right == null){
return left ;
}
return root ;
}
}
17. Reconstrua a árvore binária
Link do tópico: Reconstruindo uma árvore binária_Niuke Topic_Niuke.com
Ideia: encontre o nó raiz e construa recursivamente as subárvores esquerda e direita.
Versão Java:
import java.util.*;
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
//二叉树的先序用来找到根节点,二叉树的中序遍历用来找到左右子树
if(pre.length == 0 || vin.length == 0){
return null ;
}
TreeNode root = new TreeNode(pre[0]) ;
for(int i=0; i<vin.length;i++){
if(pre[0] == vin[i]){
root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(vin, 0, i)) ;
root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length), Arrays.copyOfRange(vin,i+1,vin.length)) ;
break ;
}
}
return root ;
}
}
Uma jornada de mil milhas começa com um único passo, e a jornada das pinceladas de outono chegará em breve.