Implementovat Trie (Prefix Strom)

Zavést trie s insertsearchstartsWith metody.

Příklad:

Trie trie = new Trie();trie.insert("apple");
trie.search("apple"); // returns true
trie.search("app"); // returns false
trie.startsWith("app"); // returns true
trie.insert("app");
trie.search("app"); // returns true

Poznámka:

  • můžete předpokládat, že všechny vstupy jsou tvořeny malými písmeny a-z.
  • všechny vstupy jsou zaručeny jako neprázdné řetězce.

toto je problém leetcode:

řešení:

než se ponoříme do řešení tohoto problému, nejprve pochopíme, co je stručná Struktura dat Trie.

Trie je uspořádaná stromová struktura, která se většinou používá k ukládání řetězců. Důvod, proč se používá k ukládání řetězec je, že má rychlý čas načítání. Složitost nalezení řetězce v Trie je O (m), kde m je délka řetězce. Pokud jsme uložili milion řetězců v Trie a potřebujeme najít konkrétní řetězec, řekněme cat, pak jeho složitost bude O (3), není to úžasné.

termín trie pochází ze slova retrieval, protože velmi usnadňuje vyhledávání řetězce ze sbírky řetězců. Trie se také nazývá jako prefixový strom.

v Trie je kořen prázdný a každý podřízený uzel obsahuje pouze jeden znak. Počet podřízených uzlů, které může mít konkrétní uzel, tedy závisí na počtu abeced v daném jazyce. Předpokládejme, že používáme naše trie k ukládání anglických slov, pak každý uzel bude mít 26 podřízených uzlů.

Na obrázku výše jsme ukázali, pouze 5 dětí, ale ve skutečné root bude mít 26 podřízené uzly, jeden pro každý abecedy.

nyní se podívejme, jestli potřebujeme reprezentovat několik řetězců v datové struktuře trie, jak to bude vypadat. Předpokládejme, že potřebujeme reprezentovat míč, plešatý, auto, kočku a psa v trie. To bude vypadat, jak je uvedeno níže. Na obrázku níže oranžové uzly znamenají konec slova.

Toto byl úvod k tomu, co Trie je, ale hlavní na tom je, jak Trie může být realizován. Podíváme se, jak lze Trie implementovat níže.

každý uzel v Trie musí obsahovat dvě informace.

  1. booleovský příznak, který říká, že tento uzel je konec slova.
  2. pole velikosti 26 (záleží na použitém jazyce. 26 je pro angličtinu). Každý index v tomto poli ukazuje na jiný uzel.

řekněme, že každý uzel v Trie je reprezentován třídou Trienod. Třída Trienod bude mít dvě pole:

  1. isEnd: Boolean field.
  2. child: pole typu TrieNode.

pak budeme mít třídu Trie, která bude obsahovat metodu insert, search a startsWith.

podívejme se, jak bude insert fungovat krok za krokem. Musíme vložit kočku do našeho trie.

  1. zpočátku máme pouze kořenový uzel. Všechny indexy v jeho poli obsahuje null a isend příznak je také false.

2. Vybereme první znak z cat, tj. nyní bude index v poli 2. Pokud si nejste vědomi, pak najdeme index libovolné abecedy v poli tím, že uděláme char – ‚a‘. Tímto způsobem je index a 0, b je 1, c je 2 a tak dále. Jdeme na index 2 pole a přiřadí mu nový uzel.

3. Nyní přesuneme ukazatel na druhý uzel. Druhá abeceda v cat je a. takže inicializujeme index 0 na nový uzel.

4. Přesuneme ukazatel na další uzel. Další abeceda v cat je t.index t je 19. Inicializujeme index 19 do nového uzlu.

5. Přejdeme k dalšímu uzlu . Nyní již není možné vložit žádnou abecedu. Takže označíme tento uzel jako konec.

Níže je Java kód pro vložení metody.

public void insert(String str) {
char data = str.toCharArray();
TrieNode tempNode = root;
for (char c : data) {
int index = c - 'a';
if (tempNode.child == null) {
tempNode.child = new TrieNode();
}
tempNode = tempNode.child;
}
tempNode.isEnd = true;
}

níže je kompletní Java řešení pro tento program s metodou vyhledávání a startsWith.

class Trie {
class TrieNode {
static final int ALPHABET_SIZE = 26;
TrieNode child = new TrieNode; boolean isEnd;
}
TrieNode root;
/**
* Initialize your data structure here.
*/
public Trie() {
root = new TrieNode();
}
/**
* Inserts a word into the trie.
*/
public void insert(String str) {
char data = str.toCharArray();
TrieNode tempNode = root;
for (char c : data) {
int index = c - 'a';
if (tempNode.child == null) {
tempNode.child = new TrieNode();
}
tempNode = tempNode.child;
}
tempNode.isEnd = true;
}
/**
* Returns if the word is in the trie.
*/
public boolean search(String str) {
char data = str.toCharArray();
TrieNode tempNode = root;
for (char c : data) {
int index = c - 'a';
if (tempNode.child == null) {
return false;
}
tempNode = tempNode.child;
}
if (tempNode != null && tempNode.isEnd == false) {
return false;
}
return true;
}
/**
* Returns if there is any word in the trie that starts with the given prefix.
*/
public boolean startsWith(String str) {
char data = str.toCharArray();
TrieNode tempNode = root;
for (char c : data) {
int index = c - 'a';
if (tempNode.child == null) {
return false;
}
tempNode = tempNode.child;
}
return true;
}
}

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.