🚀👨‍💻Resolvendo Exercicios de algoritmos do LeetCode: Numero palíndromo (Palindrome Number)🚀👨‍💻

Fala devs! Hoje, estou animado para compartilhar com vocês um vídeo onde abordo um dos problemas que enfrentei: "Palindrome Number". Neste vídeo, exploro passo a passo como resolver este desafio, aplicando conceitos de lógica e algoritmos. 🎥🔍

👍🏼 A sua opinião é fundamental! Se assistirem ao vídeo e tiverem alguma crítica ou sugestão, peço sinceramente que compartilhem nos comentários e deixem o vosso like. Acredito firmemente que a troca de feedback nos ajuda a crescer juntos e a melhorar a qualidade do conteúdo que compartilho. 🙏📝

Assistam ao vídeo aqui: Link do Vídeo do YouTube - Palindrome Number

Vamos continuar aprendendo e evoluindo juntos! 🚀✨

Só pra complementar, além de transformar o número em string, tem também a solução matemática. A mais comum que se vê por aí é a de construir o número inverso e comparar com o original:

// gerar o número inverso de "num" e comparar com o original
function isPalindrome(num) {
    // segundo o enunciado, número negativo não é palíndromo
    if (num < 0)
        return false;

    var n = num;
    var inverso = 0;
    while (n > 0) {
        inverso = (10 * inverso) + (n % 10);
        n = Math.floor(n / 10);
    }
    return num == inverso;
}

Mas na verdade dá pra otimizar, pois só precisamos ir até a metade do número:

// gera o inverso, mas só até a metade do número
function isPalindrome(n) {
    // primeiro elimina os casos mais simples
    if (n < 0) // segundo o enunciado, número negativo não é palíndromo
        return false;
    if (n < 10) // número com 1 dígito sempre é palíndromo
        return true;
    if (n % 10 == 0) // múltiplos de 10 nunca são palíndromos
        return false;
    if (n < 100) // número com 2 dígitos, compara o primeiro e segundo dígitos
        return n % 10 === Math.floor(n / 10);

    // para os demais, inverter o número até a metade
    var inverso = 0;
    while (inverso < n) {
        inverso = (10 * inverso) + (n % 10);
        n = Math.floor(n / 10);
    }
    return n == inverso || n == Math.floor(inverso / 10);
}

Primeiro eu elimino os casos mais básicos, e depois vou construindo o número inverso, mas o detalhe é que eu só vou até a metade.

Por exemplo, se o número é 1221, primeiro eu pego o último dígito, então o inverso passa a ser 1. Depois divido o número por 10, passando a ser 122.

Depois pego o último dígito (2) e adiciono ao final do inverso. Para isso, primeiro eu o multiplico por 10, então 1 passa a ser 10, e depois somo o 2, passando a ser 12. Depois divido o número 122 por 10, e ele vira 12. Com isso o loop se encerra e no final eu comparo ambos. Se forem iguais, é palíndromo.

O problema é quando a quantidade de dígitos é ímpar. Por exemplo, o número 12321. Ao final do loop, o inverso é 123 e o número é 12, então eu preciso comparar também com o inverso dividido por 10 para descontar o último dígito.


Pode até parecer pior porque "tem mais linhas", mas dependendo do caso, pode ser mais eficiente do que transformar o número em string. Fazendo testes com o Benchmark.js (e que também está disponível no JsBench), vi que depende do caso. Para um único número, a string geralmente se sai melhor, mas em um loop verificando vários (milhões de números diferentes), a solução matemática se mostrou até duas vezes mais rápida (a que vai até a metade do número se sai bem melhor que a que gera o número inverso completo).

Claro que para poucos números pequenos, a diferença será irrisória e imperceptível, mas enfim, foi só pra constar que nem sempre a solução que parece mais simples é a "melhor", e caso seja preciso, é bom saber que existem alternativas. Converter números para string (e vice-versa) não costuma escalar tão bem quanto cálculos simples. E claro que depende dos casos de uso, se a diferença de desempenho é realmente relevante para o volume de dados, etc.