Encontre a sequência mais longa sem repetir caracteres

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:

  1. a substring atual com caracteres não repetitivos com a ajuda de um índicestarteend

  2. a substring não repetida mais longaoutput

  3. 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.