implementeer een trie met insert
search
, en startsWith
methoden.
voorbeeld:
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
opmerking:
u mag aannemen dat alle invoer bestaat uit kleine letters a-z
.
alle ingangen zijn gegarandeerd niet-lege tekenreeksen.
Dit is een leetcode probleem:
oplossing:
voordat we dieper ingaan op het oplossen van dit probleem, zullen we eerst begrijpen wat de Trie data structuur in het kort is.
een Trie is een geordende boomstructuur die meestal wordt gebruikt om String op te slaan. De reden dat het wordt gebruikt om String op te slaan is dat het een snelle retrieval tijd heeft. De complexiteit van het vinden van een String in een Trie is O(m), waarbij m de lengte van de string is. Als we een miljoen snaren hebben opgeslagen in Trie en we moeten een bepaalde snaar vinden, laten we zeggen cat dan zal de complexiteit O(3) zijn, is het niet verbazingwekkend.
De term trie kwam van het woord retrieval omdat het het ophalen van een string uit de verzameling strings heel eenvoudig maakt. Trie wordt ook wel als prefix boom.
in Trie is de root leeg en elke onderliggende node bevat slechts één teken. Dus het aantal onderliggende knooppunten, een bepaald knooppunt kan hebben hangt af van het aantal alfabetten in een bepaalde taal. Stel dat we onze trie gebruiken om Engelse woorden op te slaan, dan zal elk knooppunt 26 kindknooppunten hebben.
hebben slechts 5 kindknooppunten getoond, maar in werkelijkheid zal root 26 kindknooppunten hebben, één voor elk alfabet.
nu, laten we eens kijken of we nodig hebben om enkele strings in trie data structuur vertegenwoordigen dan hoe het eruit zal zien. Stel dat we bal, kaal, auto, kat en hond moeten vertegenwoordigen in trie. Dit zal eruit zien zoals hieronder getoond. In de onderstaande afbeelding betekent de oranje knooppunten het einde van het woord.
Dit was een inleiding naar wat Trie is, maar het belangrijkste is hoe Trie kan worden geïmplementeerd. We zullen hieronder bekijken hoe Trie kan worden geïmplementeerd.
elk knooppunt in Trie moet twee stukjes informatie bevatten.
een Booleaanse vlag die aangeeft dat dit knooppunt het einde van een woord is.
een array van grootte 26 (afhankelijk van de gebruikte taal. 26 is voor Engels). Elke index in deze array wijst naar een ander knooppunt.
laten we zeggen dat elk knooppunt in Trie wordt vertegenwoordigd door TrieNode klasse. De TrieNode klasse zal twee velden hebben:
isEnd: Boolean field.
kind: een array van type TrieNode.
dan hebben we een Trie klasse die insert, search en startsWith methode zal bevatten.
laten we eens kijken hoe insert stap voor stap zal werken. We moeten cat in onze trie steken.
aanvankelijk hebben we alleen root node. Alle indexen in de array bevat null En isend flag is ook false.
2. We kiezen het eerste karakter van cat i. e c. nu zal de index in array 2 zijn. Als u zich niet bewust bent dan vinden we de index van een alfabet in array door het doen van char-‘a’. Door dit te doen is de index van a 0, b is 1, c is 2 enzovoort. We gaan naar index 2 van array en toewijzen het een nieuw knooppunt.
3. Nu verplaatsen we onze pointer naar het tweede knooppunt. Het tweede alfabet in cat is a. dus we initialiseren index 0 naar nieuwe knoop.
4. We verplaatsen de aanwijzer naar het volgende knooppunt. Het volgende alfabet in cat is t. de index van t is 19. We initialiseren index 19 naar nieuw knooppunt.
5. We gaan naar het volgende knooppunt . Nu is er geen alfabet meer om in te voegen. Dus we markeren dit knooppunt als einde.
hieronder staat de Java-code voor insert-methode.
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; }
Hieronder is de complete Java oplossing voor dit programma met search and startsWith methode.
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; } }