Removendo o N-ésimo Nó do Final de uma Lista Ligada com Técnica de Dois Ponteiros

No problema 19 do LeetCode, a meta é remover o N-ésimo nó contado a partir do final de uma lista ligada. Aqui, exploramos duas soluções alternativas.

Solução 1: Utilizando o Comprimento da Lista

Esta abordagem determina o tamanho total da lista para localizar a posição exata do nó a ser removido. Primeiro, calcula-se o comprimento; depois, encontra-se o nó predecessor e realiza-se a remoção. Atenção ao caso em que o primeiro nó deve ser eliminado.

/**

  • Definição para nó de lista ligada simples.
  • public class ListNode {
  • int dados;
    
  • ListNode proximo;
    
  • ListNode() {}
    
  • ListNode(int dados) { this.dados = dados; }
    
  • ListNode(int dados, ListNode proximo) { this.dados = dados; this.proximo = proximo; }
    
  • } */ class Solucao { public ListNode eliminarNesimoFim(ListNode inicio, int n) { ListNode iterador = inicio; int tamanho = 0; while (iterador != null) { iterador = iterador.proximo; tamanho++; } if (n == tamanho) { return inicio.proximo; } int deslocamento = tamanho - n - 1; ListNode referencia = inicio; while (deslocamento-- > 0) { inicio = inicio.proximo; } inicio.proximo = inicio.proximo.proximo; return referencia; } }

</details>### Solução 2: Aplicando Dois Ponteiros

Nesta técnica, dois ponteiros se movem de forma escalonada. O ponteiro avançado percorre n posições primeiro, e então ambos avançam simultaneamente até que o avançado chegue ao final. Isso faz com que o ponteiro atrasado aponnte para o nó anterior ao alvo, facilitando a remoção. O caso especial para o primeiro nó também é tratado.

<details><summary>Exibir código</summmary>```

/**
 * Definição para nó de lista ligada simples.
 * public class ListNode {
 *     int dados;
 *     ListNode proximo;
 *     ListNode() {}
 *     ListNode(int dados) { this.dados = dados; }
 *     ListNode(int dados, ListNode proximo) { this.dados = dados; this.proximo = proximo; }
 * }
 */
class Solucao {
    public ListNode eliminarNesimoFim(ListNode inicio, int n) {
        ListNode sentinela = new ListNode(0, inicio);
        ListNode atrasado = sentinela;
        ListNode avancado = sentinela;
        for (int i = 0; i < n; i++) {
            avancado = avancado.proximo;
        }
        if (avancado.proximo == null) {
            return inicio.proximo;
        }
        while (avancado.proximo != null) {
            avancado = avancado.proximo;
            atrasado = atrasado.proximo;
        }
        atrasado.proximo = atrasado.proximo.proximo;
        return inicio;
    }
}

Tags: Lista Ligada Dois Ponteiros java LeetCode algoritmo

Publicado em 6-15 18:46 por Thomas