LeetCode基礎 字串 Trie

2021-08-10 14:51:30 字數 3396 閱讀 8646

trie 來自單詞 retrieval,發音為 try(避免與tree混淆),也叫做單詞查詢樹,或字典樹

trie 是樹結構,除根結點外,每個結點都只會有乙個父結點。每個結點都有 r 個子結點, r 是字母表的大小,而且可能含有大量的空結點。

假設有字串:「she sells sea shells by the sea shore」,可以儲存成下面這樣,讓根結點為空:

我們將每個 字串 關聯的值儲存在這個 字串 的最後乙個字母對應的結點中,值為空的結點在符號表中沒有對應的 key。

從樹中查詢字串時,只需要一層層查詢,當到達的最後乙個字母指向的結點或者遇到了空結點時,可能有3種情況:

插入字串

插入前需要進行一次查詢,當到達最後乙個結點或空時,可能有兩種情況:

基於trie 的資料結構

public

class triest

public value get(string key)

return (value) x.val;

}private node get(node x, string key, int d)

if (d == key.length())

char c = key.charat(d); // use dth key char to identify subtrie.

return

get(x.next[c], key, d+1);

}public

void

put(string key, value val)

private node put(node x, string key, value val, int d)

if (d == key.length())

char c = key.charat(d); // use dth key char to identify subtrie.

x.next[c] = put(x.next[c], key, val, d+1);

return x;}}

遍歷所有字串

因為字串和值是隱式地儲存在 trie 中,所有遍歷要麻煩一些。

遍歷時,當訪問乙個結點時,如果它的值為空(不是最後乙個字母),則把它的後續結點放進佇列中,然後遞迴地訪問它的後續結點列表。

**如下:

public list keys()

public list keyswithprefix(string pre)

private

void

collect(node x, string pre, queue q)

if(x.val != null)

for(char c = 0; c < r; c++)

}

遍歷的過程如下圖:

字首匹配

萬用字元匹配

public list keysthatmatch(string pat)

private

void

collect(node x, string pre, queue pat, queue q)

if(d == pat.length() && x.val != null)

if(d == pat.length())

char next = pat[d];

for(char c = 0; c < r; c++)}}

最長字首找最長字首時,會記錄查詢路徑上找到的最長字串的長度。

public string longestprefixof(string s)

private

intsearch(node x, string s, int d, int length)

if (x.val != null)

if (d == s.length())

char c = s.charat(d);

return search(x.next[c], s, d+1, length);

}

如下圖:

刪除字串

從 trie 中刪去乙個字串的第一步是:找到字串所對應的結點,把它的值設定為 null。如果這個結點含有乙個非空的鏈結指向其他子結點,則不需要其他操作。如果它的子結點為空,那就需要從 trie 中刪除這個結點,直到子結點不為空時。

public

void

delete(string key)

private node delete(node x, string key, int d)

if (d == key.length())

else

if (x.val != null)

for (char c = 0; c < r; c++)

}return

null;

}

如下圖:

c# 實現簡單的 trie 結構(內部用hashmap儲存)

public

class trie

public

void

add(string s)

if (next == null)

runnode = children[c];

}runnode.isend = true;}}

public

class trienode

public dictionary children

public

trienode()

}

Linux 指令篇 字串處理 tr

名稱 tr 1.比方說要把目錄下所有的大寫檔名換為小寫檔名?似乎有很多方式,tr 是其中一種 bin sh dir tmp testdir files find dir type f for i in files do dir name dirname i ori filename basename...

LeetCode 字串 反轉字串

反轉字串 編寫乙個函式,其作用是將輸入的字串反轉過來。輸入字串以字元陣列char的形式給出。不要給另外的陣列分配額外的空間,你必須原地修改輸入陣列 使用 o 1 的額外空間解決這一問題。你可以假設陣列中的所有字元都是 ascii 碼表中的可列印字元。示例 1 輸入 h e l l o 輸出 o l ...

LeetCode 字串 親密字串

給定兩個由小寫字母構成的字串 a 和 b 只要我們可以通過交換 a 中的兩個字母得到與 b 相等的結果,就返回 true 否則返回 false 示例 輸入 a ab b ba 輸出 true 輸入 a ab b ab 輸出 false 輸入 a aa b aa 輸出 true 遍歷字串 a,記錄 a...