題目描述:哦,不!你不小心把乙個長篇文章中的空格、標點都刪掉了,並且大寫也弄成了小寫。像句子"i reset the computer. it still didn』t boot!「已經變成了"iresetthecomputeritstilldidntboot」。在處理標點符號和大小寫之前,你得先把它斷成詞語。當然了,你有一本厚厚的詞典dictionary,不過,有些詞沒在詞典裡。假設文章用sentence表示,設計乙個演算法,把文章斷開,要求未識別的字元最少,返回未識別的字元數。
注意:本題相對原題稍作改動,只需返回未識別的字元數
解題思路一:雜湊字串+動態規劃,從最左邊到當前位置的字串的未識別字元可以由字首字串的結果得到,最大不過為dp[i-1]+1,然後從當前位置依次往前擷取子字串看是否可以匹配,可以的話就更新dp[i]
,等於min(dp[i], d[j])
,j是擷取的子字串前面的字串未識別的字元數量,但這個雜湊函式的設計不是很懂,為什麼這樣設計,**如下:
class
solution
:def
respace
(self, dictionary: list[
str]
, sentence:
str)
->
int:
base =
41 p =
1<<31-
1def
get_hashcode
(s):
val =
0 size =
len(s)
for i in
range
(size-1,
-1,-
1): val = val * base +
ord(s[i])-
97+1 val %= p
return val
code =
set(
)for d in dictionary:
code.add(get_hashcode(d)
) size =
len(sentence)
dp =
[size]
*(size+1)
dp[0]
=0for i in
range(1
, size+1)
: dp[i]
= dp[i-1]
+1c =
0for j in
range
(i-1,-
1,-1
):c = c * base +
ord(sentence[j])-
97+1 c %= p
if c in code:
dp[i]
=min
(dp[i]
, dp[j]
)return dp[-1
]
解題思路二:字首樹+動態規劃,思路和方法一是一樣的,只是匹配過程轉化為字首樹的方式,可以提前結束匹配過程,如果從當前位置往前的字尾不匹配,那麼也沒有必要再往前匹配下去,將字典中的字元倒序用字首樹儲存即可,**如下:
class
solution
:def
respace
(self, dictionary: list[
str]
, sentence:
str)
->
int:
class
trie()
:def
__init__
(self)
: self.root =
self.end_word =-1
definsert
(self, word)
: curnode = self.root
for c in word:
if c not
in curnode:
curnode[c]
= curnode = curnode[c]
curnode[self.end_word]
=true
root = trie(
)for d in dictionary:
root.insert(d[::
-1])
size =
len(sentence)
dp =
[size]
*(size+1)
dp[0]
=0for i in
range(1
, size+1)
: dp[i]
= dp[i-1]
+1curnode = root.root
for j in
range
(i-1,-
1,-1
):if sentence[j]
notin curnode:
break
curnode = curnode[sentence[j]]if
-1in curnode:
dp[i]
=min
(dp[i]
, dp[j]
)if dp[i]==0
:break
return dp[-1
]
面試題17 13 恢復空格
刷題主頁 一看就是給定字串和字典,檢視是否匹配類的問題,因此直接考慮動態規劃,dp i 表示前i個字元未識別的字元最少數,那麼當s j 1 i 在字典中時,dp i min dp i dp j 1 否則dp i dp i 1 1 整體和單詞拆分類似,雙重迴圈 判斷即可。class solution ...
面試題 17 13 恢復空格
哦,不!你不小心把乙個長篇文章中的空格 標點都刪掉了,並且大寫也弄成了小寫。像句子 i reset the computer.it still didn t boot 已經變成了 iresetthecomputeritstilldidntboot 在處理標點符號和大小寫之前,你得先把它斷成詞語。當然...
面試題 17 13 恢復空格
哦,不!你不小心把乙個長篇文章中的空格 標點都刪掉了,並且大寫也弄成了小寫。像句子 i reset the computer.it still didn t boot 已經變成了 iresetthecomputeritstilldidntboot 在處理標點符號和大小寫之前,你得先把它斷成詞語。當然...