Pular para o conteudo principal

K-ésimo menor elemento em uma árvore binária de busca

Como usar o percurso em ordem para explorar a ordem natural da árvore binaria de busca e parar assim que o contador chega em k.

Dada a raiz de uma árvore binaria de busca e um inteiro k, retorne o k-esimo menor valor da árvore.

Considere k como indice baseado em 1.

Exemplo:

Input:
  root = [3,1,4,null,2]
  k = 1

Output:
  1

O que perceber antes de codar

Erros comuns

Passo 1 - Lembrar o que a árvore te entrega de graca

Em uma árvore binaria de busca:

  • tudo da esquerda e menor
  • tudo da direita e maior

Isso significa que existe uma travessia que já devolve os valores em ordem.

Essa travessia e o percurso em ordem:

  • esquerda
  • no atual
  • direita

Passo 2 - Escrever a versão inicial mais direta

A versão inicial boa e:

  • fazer o percurso em ordem completo
  • guardar os valores em array
  • devolver values[k - 1]

Funciona e deixa a propriedade ordenada bem visível.

Passo 3 - Perguntar o que realmente precisa ser guardado

O problema não pede todos os valores ordenados.

Ele pede só:

  • o k-esimo visitado

Entao talvez um array inteiro seja mais do que você precisa.

Passo 4 - Contar durante o percurso em ordem e parar cedo

Em vez de guardar tudo, você pode:

  • manter um contador
  • incrementar a cada visita real
  • parar quando o contador chegar em k

Isso transforma a propriedade da árvore em resposta direta.

O editor interativo precisa de JavaScript. Voce ainda pode ler o desafio e copiar o codigo inicial abaixo.

Codigo inicial

export function kthSmallest(root, k) {
  // root is an object like { val: number, left: ..., right: ... } or null
  // sua solução aqui
  return null
}
solution.ts
Travado? Dicas disponiveis.

Ainda não resolveu?

Ver a solução agora pode reduzir o aprendizado. Vale a pena tentar mais um pouco.

Abrir a solucao de referencia

Sem JavaScript, a solucao de referencia aparece inline em vez de um dialogo.

Solução

Complexidade final

Tempo: O(h + k)

Espaço: O(h)

Solução 1 - Percurso em ordem completo mais array

Boa versão inicial porque deixa a ordem natural da árvore bem explicita.

export function kthSmallest(root, k) {
  const values = []

  function inorder(node) {
    if (node === null) {
      return
    }

    inorder(node.left)
    values.push(node.val)
    inorder(node.right)
  }

  inorder(root)
  return values[k - 1] ?? null
}

Funciona.

Mas guarda mais estado do que o problema realmente pede.

Solução 2 - Percurso em ordem com contador e parada antecipada na busca em profundidade (DFS)

Agora a travessia para assim que encontra a resposta.

export function kthSmallest(root, k) {
  let seen = 0
  let result = null

  function inorder(node) {
    if (node === null || result !== null) {
      return
    }

    inorder(node.left)

    if (result !== null) {
      return
    }

    seen += 1

    if (seen === k) {
      result = node.val
      return
    }

    inorder(node.right)
  }

  inorder(root)
  return result
}

O insight forte aqui e que esse percurso não e só uma travessia bonita. E a forma de ler a árvore binaria de busca em ordem.

O que dizer na entrevista

Uma explicação curta e boa seria:

Como a estrutura e uma árvore binaria de busca, o percurso em ordem visita os valores em ordem crescente. A versão inicial faz esse percurso completo e pega values[k - 1]. A versão melhor só conta quantos nos já visitou e para assim que chega no k-esimo, sem precisar guardar tudo, entao a travessia só vai até onde a resposta obrigar.

Isso mostra que você:

  • usou uma propriedade da estrutura, não força bruta
  • deixou claro por que o percurso em ordem e a travessia certa
  • evitou estado desnecessario

Quando esse padrão aparece de novo

Esse padrão reaparece quando você precisa:

  • ler árvore binaria de busca em ordem crescente
  • buscar posição relativa em estrutura ordenada
  • transformar travessia em contador
  • decidir quando vale parar cedo numa busca em profundidade (DFS)

O ponto não e decorar esse problema.

O ponto e aprender quando a ordem já esta embutida na própria estrutura.

Proximo desafio Mínimo de salas de reunião Desafio anterior Subárvore de outra árvore

Desafios relacionados

Artigos relacionados