Minha Estratégia para Estudar LeetCode
Sumário
Antes de tudo, não se pressione. Foque no longo prazo, fazendo um pouco todos os dias ou encaixando isso na sua agenda e seguindo o plano, combinado?
Com isso em mente, esta é minha estratégia para estudar LeetCode.
1. Comece pelo básico
No momento, estou estudando o básico de algoritmos, com foco em manipulação de strings no LeetCode, filtrando pelos problemas fáceis. Neste post,
vou mostrar passo a passo o exercício 125. Valid Palindrome do LeetCode.
2. Estude o problema
Neste ponto, você deve ler e entender o problema. Você pode ver o problema aqui.
3. Escreva o código
Agora vou começar a explicar como estudo no LeetCode. Primeiro, foco em simplesmente resolver o problema, sem me preocupar em encontrar a solução mais otimizada. O objetivo é só ter uma solução que funcione, combinado?
Neste exemplo, começo resolvendo o problema com o seguinte código:
func isPalindrome(s string) bool {
var reversed string
var newS string
for _, v := range s {
if unicode.IsLetter(v) || unicode.IsDigit(v) {
reversed += strings.ToLower(string(v))
newS = strings.ToLower(string(v)) + newS
}
}
return reversed == newS
}
Percebi que esta solução leva 1067 ms e usa 80,2 MB de memória. Nesse ponto, começo a procurar formas de melhorá-la.
4. Otimize o código
Aqui, trabalho para deixar a solução mais rápida e mais eficiente em memória:
func isPalindrome(s string) bool {
var stringReversed string
var sNew string
lenString := len(s)
count := 0
for count != lenString {
if unicode.IsLetter(rune(s[count])) || unicode.IsDigit(rune(s[count])) {
sNew += strings.ToLower(string(s[count]))
stringReversed = strings.ToLower(string(s[count])) + stringReversed
}
count++
}
return sNew == stringReversed
}
Notei que a solução atualizada agora leva 976 ms e usa 48,5 MB de memória.
Nesse ponto, continuo refinando para ver se ainda dá para melhorar.
5. A última melhoria
Então percebi que, para validar um palíndromo, não preciso guardar nada em memória; só preciso comparar os caracteres em posições específicas. Com essa abordagem, minha solução melhorou muito.
func isPalindrome(s string) bool {
for i, j := 0, len(s)-1; i < j; {
if !isAlphaNumeric(s[i]) {
i++
} else if !isAlphaNumeric(s[j]) {
j--
} else if strings.ToLower(string(s[i])) != strings.ToLower(string(s[j])) {
return false
} else {
i++
j--
}
}
return true
}
func isAlphaNumeric(s byte) bool {
return (s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || (s >= '0' && s <= '9')
}
Vi que esta solução otimizada agora leva 0 ms e usa apenas 4,5 MB de memória.
Nesse ponto, vejo se ainda há espaço para melhorias, embora a solução já seja muito eficiente.
Aqui está um print das soluções no LeetCode:

6. Conclusão
Nestes passos, mostrei minha forma de estudar no LeetCode:
Primeiro, resolvo o problema sem me preocupar em encontrar a solução ideal, focando só em fazê-lo funcionar. Depois, tento refinar a solução para usar menos memória e rodar mais rápido. Por fim, penso em simplificações adicionais. Por exemplo, para validar um palíndromo, percebi que não preciso guardar nada em memória; só preciso comparar posições específicas dos caracteres. Essa abordagem melhorou muito minha solução. Esse método tem me ajudado a escrever código melhor no dia a dia, e espero que ajude você também!
Bons códigos! 🚀