Palindrome String
Uma string é um palíndromo quando é lida da mesma forma da esquerda para a direita e da direita para a esquerda, como level. Escreva uma função que receba uma string s com letras minúsculas do alfabeto inglês e retorne true se s for um palíndromo e false caso contrário.
Função
- sstring
- a string em letras minúsculas a ser verificada
- Retornaboolean
- verdadeiro quando s é lido da mesma forma nas duas direções
Restrições
1 ≤ s.length ≤ 5 × 104scontém apenas letras minúsculas do inglês (aaz).
Exemplos
- Entrada
- s = "racecar"
- Saída
- true
- Explicação
- Compare de fora para dentro:
rcomr,acoma,ccomc. Oedo meio não tem par e não precisa de um, então a resposta étrue.
- Entrada
- s = "abba"
- Saída
- true
- Explicação
- Com um comprimento par, cada letra tem um par: os dois
as combinam e os doisbs combinam, então a resposta étrue.
- Entrada
- s = "coddy"
- Saída
- false
- Explicação
- A primeira letra
ce a última letrayjá são diferentes, entãocoddynão é um palíndromo e a resposta éfalse.
Para ir além
Como você alteraria os dois ponteiros para ignorar espaços e pontuação e desconsiderar maiúsculas e minúsculas, de modo que Was it a car or a cat I saw seja considerado um palíndromo?
Dicas
Abra uma de cada vez. Cada uma revela um pouco mais.
Se
sfor um palíndromo, a qual caractere o primeiro caractere deve ser igual?O caractere no índice
ideve ser igual ao do índicen-1-i. Cada par desse tipo só precisa ser verificado uma vez, então metade dos índices é suficiente.Coloque um índice no início e outro no final. Compare os dois caracteres, retorne
falsese forem diferentes e mova ambos os índices um passo para dentro até que se encontrem.
Solução
Um palíndromo é igual à sua própria versão invertida, então você pode criar a versão invertida e compará-las. Você não precisa da cópia: o primeiro caractere deve corresponder ao último, o segundo ao penúltimo, e assim por diante. Dois índices que avançam em direção ao centro testam esses pares no próprio lugar e param na primeira divergência.
Compare a string com sua inversa
Intuição
Inverta s e compare: racecar invertida é racecar, e coddy invertida é yddoc. Uma string é lida da mesma forma nos dois sentidos exatamente quando é igual à sua inversa.
O tempo é O(n), mas a cópia invertida ocupa O(n) de espaço extra: 50.000 caracteres para n = 5 × 10^4. O trabalho também é sempre completo: o caso de coddy é decidido pelas primeiras e últimas letras, mas as cinco letras são invertidas primeiro.
Algoritmo
- Construa o inverso de
s, usando a função de inversão da linguagem ou um loop do último caractere ao primeiro. - Compare o inverso com
s. - Retorne
truese forem iguais efalsecaso contrário.
def isPalindrome(s):
return s == s[::-1]Dois ponteiros, um em cada extremidade
Intuição
Inverter move o índice i para o índice n-1-i, então s é igual ao seu reverso exatamente quando s[i] é igual a s[n-1-i] para todo i. Cada par aparece duas vezes nessa condição, então basta verificar a metade esquerda. Em racecar, os pares são (0, 6), (1, 5) e (2, 4); o e central no índice 3 não precisa de par.
O primeiro par diferente prova que a resposta é false, então a decisão para coddy é tomada após uma comparação. No máximo n / 2 comparações são executadas, com tempo O(n), e dois índices ocupam espaço O(1). R primeiro lê a string como um vetor de códigos de caracteres, o que custa O(n).
Algoritmo
- Defina
left = 0eright = n-1. - Enquanto
left < right, compares[left]coms[right]. - Se forem diferentes, retorne
false. - Caso contrário, some 1 a
left, subtraia 1 derighte repita. - Quando os ponteiros se encontrarem ou se cruzarem, todos os pares corresponderão: retorne
true.
def isPalindrome(s):
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
Armadilhas e casos extremos
- Retornar
trueassim que um par corresponder.abcapassa pelo par externo e falha no interno, entãotruesó é retornado após o loop. - Começar
rightemnem vez den-1, o que acessa uma posição além do fim (em C, o'\0'terminador). Em Lua e R, os índices vão de 1 an, então, nesses casos,rightcomeça emn. - Comparar strings com
==em C.reversed == scompara dois ponteiros e é falso para uma cópia; usestrcmp. - Construir a string invertida com
result = result + ch. Cada etapa copia a string construída até então: cerca de1.25 × 10^9cópias de caracteres para 50.000 letras. - Acessar uma string Swift usando um inteiro como índice: isso não compila. Percorra
s.utf8ou copie os caracteres para um array.
Perguntas frequentes4
Como verificar se uma string é um palíndromo?
Compare o primeiro caractere com o último, o segundo com o penúltimo e assim por diante, em direção ao meio. Se algum par for diferente, a string não é um palíndromo. Dois índices que começam nas duas extremidades e avançam para o centro fazem isso em uma única passagem.
Você consegue verificar se uma palavra é um palíndromo sem usar memória extra?
Sim. A verificação com dois ponteiros lê os caracteres no próprio lugar e armazena dois índices, então usa O(1) de espaço extra. Comparar s com sua versão invertida é mais curto de escrever, mas cria uma segunda string de n caracteres.
Qual é a complexidade de tempo para verificar se uma string é um palíndromo?
O(n) para uma string de comprimento n. A verificação com dois ponteiros faz no máximo n / 2 comparações e para na primeira divergência, então coddy requer uma comparação.
Um único caractere é um palíndromo?
Sim, a leitura é a mesma nas duas direções. No loop de dois ponteiros, left e right começam ambos no índice 0, o loop nunca é executado e a função retorna true.
Problemas parecidos
Problemas que usam as mesmas ideias. Resolver dois ou três é o que fixa um padrão.
def isPalindrome(s):
# Escreva o código aquiTeste #1
Teste #2
Teste #3
Argumento
s = "racecar"
Saída Esperada
true