Finde den längsten Teilstring ohne sich wiederholende Zeichen

Finde den längsten Teilstring ohne wiederholte Zeichen

1. Überblick

Vergleichen Sie in diesem Lernprogramm die Möglichkeiten, um mithilfe von Java die längste Teilzeichenfolge eindeutiger Buchstaben zu finden. Die längste Unterzeichenfolge von eindeutigen Buchstaben in "CODINGISAWESOME" ist beispielsweise "NGISAWE".

2. Brute-Force-Ansatz

Beginnen wir mit einem naiven Ansatz. Zunächstwe 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;
}

Da esn*(n+1)/2 mögliche Teilzeichenfolgen gibt,the time complexity of this approach is O(n^2).

3. Optimierter Ansatz

Schauen wir uns nun einen optimierten Ansatz an. Wir beginnen die Zeichenkette von links nach rechts zu durchlaufen und behalten den Überblick über:

  1. die aktuelle Teilzeichenfolge mit sich nicht wiederholenden Zeichen mithilfe eines Index vonstart undend

  2. der längste sich nicht wiederholende Teilstringoutput

  3. eine Nachschlagetabelle mit bereitsvisitedZeichen

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;
}

Für jeden neuen Charakter suchen wir ihn in den bereits besuchten Charakteren. Wenn das Zeichen bereits besucht wurde und Teil der aktuellen Teilzeichenfolge mit nicht wiederholenden Zeichen ist, aktualisieren wir den Startindex. Andernfalls werden wir den String weiter durchlaufen.

Da wir den String nur einmal durchlaufen,the time complexity will be linear, or O(n).

Dieser Ansatz wird auch alssliding window pattern bezeichnet.

4. Testen

Lassen Sie uns abschließend unsere Implementierung gründlich testen, um sicherzustellen, dass sie funktioniert:

@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"));
}

Hier versuchen wir undtest boundary conditions as well as the more typical use cases.

5. Fazit

In diesem Tutorial haben wir gelernt, wie Sie mithilfe der Schiebefenstertechnik den längsten Teilstring mit sich nicht wiederholenden Zeichen finden.

Und wie immer ist der Quellcodeover on GitHub verfügbar.