給定乙個單詞列表,我們將這個列表編碼成乙個索引字串 s 與乙個索引列表 a。
例如,如果這個列表是 [「time」, 「me」, 「bell」],我們就可以將其表示為 s = 「time#bell#」 和 indexes = [0, 2, 5]。
對於每乙個索引,我們可以通過從字串 s 中索引的位置開始讀取字串,直到 「#」 結束,來恢復我們之前的單詞列表。
那麼成功對給定單詞列表進行編碼的最小字串長度是多少呢?
示例:
輸入: words = ["time", "me", "bell"]
輸出: 10
說明: s = "time#bell#" , indexes = [0, 2, 5] 。
1 <= words.length <= 2000
1 <= words[i].length <= 7
每個單詞都是小寫字母 。
思路分
析:\color思路分析:
思路分析
:這道題的題意很清晰,就是如果有乙個單詞的字尾是另外乙個單詞,則可以將這兩個單詞合併在一起。比如示例中的"time"和"me",第乙個單詞的字尾"me"是第乙個單詞,所有我們可以將它們合併為"time#"。
如果我們將所有的單詞翻轉一下,這是不是就是讓我們構建乙個棵字首樹?
關於字首樹請翻閱 leetcode 實現trie(字首樹)
//字首樹的程式表示
class
trienode
~trienode()
};class
solution
//第二步:開始搜尋樹中每條路徑的長度
myfindcount
(trieroot,1)
;//注意起始節點深度為1,"time#"中的字元'#'
return rescount;
}//往樹中新增乙個單詞以及對應的權重
void
addword
(const string &word)
ptr = ptr-
>children[
*rit -
'a'];}
ptr-
>isword =
true
;//標記為單詞
}//尋找以root為根的路徑長度(深度)
由於字首樹在構造樹、計算所有路徑長度的時候會耗費大量時間,在儲存字首樹時也會耗費大量空間。
蛋式這道題也可以不需要字首樹,我們首先將words中的單詞進行翻轉,然後將words進行公升序排序,比如示例翻轉單詞再排序後就是words = [「em」, 「emit」, 「lleb」],這樣可以看出如果存在字首關係,它們必定相鄰並且後乙個字串以前乙個字串為起始。
class
solution
//第二步:進行公升序排序
sort
(words.
begin()
, words.
end())
;int rescount =
0, wordssize = words.
size()
;//第三步:確定壓縮後的長度
for(
int i =
0; i < wordssize;
++i)
rescount +
= words[i]
.size()
+1;//注意需要新增'#'字元的長度
leetcode單詞的壓縮編碼
1.反轉 排序 當乙個字串是另乙個字串的字尾時,該字串可以省略,如me是time的字尾 首先遍歷字串陣列,反轉每乙個字串,然後將字串陣列按照字典需排列 如time me bell 反轉emit em lleb 按字典序排列 em emit lleb 只需要比較相鄰的字串是否後乙個包含前乙個即可 如e...
Leetcode之 單詞的壓縮編碼
給定乙個單詞列表,我們將這個列表編碼成乙個索引字串 s 與乙個索引列表 a。例如,如果這個列表是 time me bell 我們就可以將其表示為 s time bell 和 indexes 0,2,5 對於每乙個索引,我們可以通過從字串 s 中索引的位置開始讀取字串,直到 結束,來恢復我們之前的單詞...
單詞的壓縮編碼
1 描述820 給定乙個單詞列表,我們將這個列表編碼成乙個索引字串 s 與乙個索引列表 a。例如,如果這個列表是 time me bell 我們就可以將其表示為 s time bell 和 indexes 0,2,5 對於每乙個索引,我們可以通過從字串 s 中索引的位置開始讀取字串,直到 結束,來恢...