Encontre a sequência mais longa sem repetir caracteres
1. Visão geral
Neste tutorial, compare maneiras de encontrar a substring mais longa de letras exclusivas usando Java. Por exemplo, a sequência mais longa de letras exclusivas em "CODINGISAWESOME" é "NGISAWE".
2. Abordagem da força bruta
Vamos começar com uma abordagem ingênua. Para começar,we can examine each substring whether it contains unique characters:
String getUniqueCharacterSubstringBruteForce(String input) {
String output = "";
for (int start = 0; start < input.length(); start++) {
Set visited = new HashSet<>();
int end = start;
for (; end < input.length(); end++) {
char currChar = input.charAt(end);
if (visited.contains(currChar)) {
break;
} else {
visited.add(currChar);
}
}
if (output.length() < end - start + 1) {
output = input.substring(start, end);
}
}
return output;
}
Como existemn*(n+1)/2 substrings possíveis,the time complexity of this approach is O(n^2).
3. Abordagem otimizada
Agora, vamos dar uma olhada em uma abordagem otimizada. Começamos a percorrer a corda da esquerda para a direita e mantemos o controle de:
-
a substring atual com caracteres não repetitivos com a ajuda de um índicestarteend
-
a substring não repetida mais longaoutput
-
uma tabela de pesquisa de jávisited caracteres
String getUniqueCharacterSubstring(String input) {
Map visited = new HashMap<>();
String output = "";
for (int start = 0, end = 0; end < input.length(); end++) {
char currChar = input.charAt(end);
if (visited.containsKey(currChar)) {
start = Math.max(visited.get(currChar)+1, start);
}
if (output.length() < end - start + 1) {
output = input.substring(start, end + 1);
}
visited.put(currChar, end);
}
return output;
}
Para cada novo personagem, procuramos nos personagens já visitados. Se o caractere já foi visitado e faz parte da substring atual com caracteres não repetidos, atualizamos o índice inicial. Caso contrário, continuaremos percorrendo a string.
Já que estamos percorrendo a string apenas uma vez,the time complexity will be linear, or O(n).
Essa abordagem também é conhecida comosliding window pattern.
4. Teste
Por fim, vamos testar completamente nossa implementação para garantir que funciona:
@Test
void givenString_whenGetUniqueCharacterSubstringCalled_thenResultFoundAsExpected() {
assertEquals("", getUniqueCharacterSubstring(""));
assertEquals("A", getUniqueCharacterSubstring("A"));
assertEquals("ABCDEF", getUniqueCharacterSubstring("AABCDEF"));
assertEquals("ABCDEF", getUniqueCharacterSubstring("ABCDEFF"));
assertEquals("NGISAWE", getUniqueCharacterSubstring("CODINGISAWESOME"));
assertEquals("be coding", getUniqueCharacterSubstring("always be coding"));
}
Aqui, tentamos etest boundary conditions as well as the more typical use cases.
5. Conclusão
Neste tutorial, aprendemos como usar a técnica de janela deslizante para encontrar a substring mais longa com caracteres não repetitivos.
E, como sempre, o código-fonte está disponívelover on GitHub.