Executando verificação de segurança...
1

Como saber se uma lista encadeada é um palíndromo?

Estava resolvendo alguns desafios do LeetCode e cheguei no Palindrome Linked List, que consiste em descobrir se uma lista encadeada é um palíndromo.

Caso você não saiba, palíndromo é uma frase ou palavra que se pode ler, indiferentemente, da esquerda para a direita ou vice-versa.

Por exemplo, a palavra reviver. Se você a ler começando pelo começo e for até o final, será a mesma coisa que a ler começando pelo final e indo até o começo. O mesmo ocorre com as palavras ana e ovo.

No caso do desafio, a lista poderia ser considerada um palíndromo se os valores lidos da esquerda para a direita fossem iguais da direita para esquerda.

O exemplo dado no desafio é:

ListNode{val: 1, next: ListNode{val: 2, next: ListNode{val: 2, next: ListNode{val: 1, next: None}}}}

Ou seja, os valores dessa lista encadeada são 1 2 2 1, que consiste em um palíndromo.

Um jeito bem famoso de resolver problemas com palíndromos em programação é com a estratégia de recursão e, no meu caso, é a estratégia preferida.

Entretanto, eu tentei resolver o desafio com recursão e deu um erro de timeout quando a lista tinha mais de 500 elementos.

Por isso, a estratégia que eu desenvolvi foi de percorrer toda a lista encadeada e criar um array com o node atual na chave val, ou seja, criar um array com todos os elementos da lista.

Com o array de N elementos criado, basta iterar sobre os N / 2 elementos e ver se o começo e o final convergem.

    def isPalindrome(self, head):
        node = head
        values = [node.val]

        while node.next:
            node = node.next
            values.append(node.val)

        size = len(values)

        for i in range(size // 2):
            if values[i] != values[size - i - 1]:
                return False

        return True

Esse algoritmo tem complexidade O(n), já que precisa iterar por todos os itens da lista encadeada e depois iterar pelos N / 2 elementos do array.

Carregando publicação patrocinada...
1

Legal.
Fiz um código aqui pra testar:

def palindromo(lista):
     fim = len(lista) - 1
     meio = fim // 2
     for i in range(0, meio):
             if lista[i] != lista[fim]:
                     return False
             fim -= 1
     return True