Pronađite najdužu podniz bez ponavljanja znakova

1. Pregled

U ovom uputstvu usporedite načine pronalaženja najdužeg niza jedinstvenih slova pomoću Jave. Na primjer, najduži podniz jedinstvenih slova u “CODINGISAWESOME” je “NGISAWE”.

2. Pristup grube sile

Krenimo od naivnog pristupa. Početi sa, možemo ispitati svaku podniz sadrži li jedinstvene znakove:

String getUniqueCharacterSubstringBruteForce (String input) {String output = ""; for (int start = 0; start <input.length (); start ++) {Postavljeno posjećeno = novi HashSet (); int kraj = početak; for (; end <input.length (); end ++) {char currChar = input.charAt (kraj); if (posjetio.sadrži (currChar)) {break; } else {posjećeno.add (currChar); }} if (output.length () <end - start + 1) {output = input.substring (početak, kraj); }} povratni izlaz; }

Budući da postoje n * (n + 1) / 2 moguće podnizove, vremenska složenost ovog pristupa je O (n ^ 2).

3. Optimizirani pristup

Sada, pogledajmo optimizirani pristup. Počinjemo obilaziti niz slijeva udesno i održavamo evidenciju:

  1. trenutni podniz sa znakovima koji se ne ponavljaju uz pomoć a početak i kraj indeks
  2. najduži ne ponavljajući se podniz izlaz
  3. pregledna tablica već posjetili likova
String getUniqueCharacterSubstring (String input) {Karta posjećena = nova HashMap (); Izlaz niza = ""; for (int start = 0, end = 0; end <input.length (); end ++) {char currChar = input.charAt (end); if (visit.containsKey (currChar)) {start = Math.max (visit.get (currChar) +1, start); } if (output.length () <end - start + 1) {output = input.substring (početak, kraj + 1); } posjećeno.put (currChar, kraj); } povratni izlaz; }

Za svaki novi lik tražimo ga u već posjećenim likovima. Ako je znak već posjećen i dio je trenutačnog podniza s neponovljivim znakovima, ažuriramo početni indeks. U suprotnom nastavit ćemo obilaziti niz.

Budući da niz prelazimo samo jednom, vremenska složenost bit će linearna, ili Na).

Ovaj pristup poznat je i kao uzorak kliznih prozora.

4. Ispitivanje

Na kraju, ispitajmo temeljito našu implementaciju kako bismo bili sigurni da djeluje:

@Test void givenString_whenGetUniqueCharacterSubstringCalled_thenResultFoundAsExpected () {assertEquals ("", getUniqueCharacterSubstring ("")); assertEquals ("A", getUniqueCharacterSubstring ("A")); assertEquals ("ABCDEF", getUniqueCharacterSubstring ("AABCDEF")); assertEquals ("ABCDEF", getUniqueCharacterSubstring ("ABCDEFF")); assertEquals ("NGISAWE", getUniqueCharacterSubstring ("CODINGISAWESOME")); assertEquals ("biti kodiranje", getUniqueCharacterSubstring ("uvijek biti kodiranje")); }

Evo, pokušavamo i testirati granične uvjete kao i tipičnije slučajeve uporabe.

5. Zaključak

U ovom smo tutorijalu naučili kako pomoću tehnike kliznih prozora pronaći najduži podniz sa znakovima koji se ne ponavljaju.

Kao i uvijek, izvorni kod dostupan je na GitHub-u.