Pracuję nad problemem z hakerem i I wierzę, moje rozwiązanie jest poprawne. Jednak większość moich przypadków testowych jest limitowana. Czy ktoś może sugerować, jak poprawić wydajność mojego kodu?Jak sprawić, by mój triest był bardziej wydajny?
Ważna część kodu rozpoczyna się od "Klasy Trie".
Dokładna pytanie można znaleźć tutaj: https://www.hackerrank.com/challenges/contacts
using System;
using System.Collections.Generic;
using System.IO;
class Solution
{
static void Main(String[] args)
{
int N = Int32.Parse(Console.ReadLine());
string[,] argList = new string[N, 2];
for (int i = 0; i < N; i++)
{
string[] s = Console.ReadLine().Split();
argList[i, 0] = s[0];
argList[i, 1] = s[1];
}
Trie trie = new Trie();
for (int i = 0; i < N; i++)
{
switch (argList[i, 0])
{
case "add":
trie.add(argList[i, 1]);
break;
case "find":
Console.WriteLine(trie.find(argList[i, 1]));
break;
default:
break;
}
}
}
}
class Trie
{
Trie[] trieArray = new Trie[26];
private int findCount = 0;
private bool data = false;
private char name;
public void add(string s)
{
s = s.ToLower();
add(s, this);
}
private void add(string s, Trie t)
{
char first = Char.Parse(s.Substring(0, 1));
int index = first - 'a';
if(t.trieArray[index] == null)
{
t.trieArray[index] = new Trie();
t.trieArray[index].name = first;
}
if (s.Length > 1)
{
add(s.Substring(1), t.trieArray[index]);
}
else
{
t.trieArray[index].data = true;
}
}
public int find(string s)
{
int ans;
s = s.ToLower();
find(s, this);
ans = findCount;
findCount = 0;
return ans;
}
private void find(string s, Trie t)
{
if (t == null)
{
return;
}
if (s.Length > 0)
{
char first = Char.Parse(s.Substring(0, 1));
int index = first - 'a';
find(s.Substring(1), t.trieArray[index]);
}
else
{
for(int i = 0; i < 26; i++)
{
if (t.trieArray[i] != null)
{
find("", t.trieArray[i]);
}
}
if (t.data == true)
{
findCount++;
}
}
}
}
EDIT: Zrobiłem pewne sugestie w komentarzach, ale uświadomiłem sobie, że nie może zastąpić s.Substring (1) ze s [0] ... ponieważ potrzebuję s [1..n]. AND s [0] zwraca znak, więc i tak będę musiał to zrobić .ToString.
Ponadto, aby dodać trochę więcej informacji. Chodzi o to, że musi zliczyć WSZYSTKIE nazwiska po prefiksie na przykład.
Input: "He"
Trie Contains:
"Hello"
"Help"
"Heart"
"Ha"
"No"
Output: 3
Staraj się nie za pomocą rekurencji, tworzysz zbyt wiele ciągów, gdy nie jest potrzebna, użyj indeksu, aby uzyskać 1 znak z łańcucha zamiast podłańcucha –
Tak, wiem, że jest to podejście iteracyjne, ale mam wrażenie, że ponieważ jest to struktura podobna do drzewa, rekurencja byłaby odpowiednia. Czuję, że zdecydowanie brakuje mi czegoś innego poza rekurencją. Podam metodę substring! Czy poleciłbym spróbować "StringBuilder"? –
Aby uzyskać pierwszy znak, możesz użyć s [0]. Ponieważ przechodzisz tylko jedną ścieżkę w drzewie, nie ma potrzeby rekursji, a wtedy nie musiałbyś używać podciągu. Nawet z rekurencją, jeśli przekazałeś w dół indeks znaku wewnątrz łańcucha, a nie podciąg, może on być szybszy. –