日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

程序员面试金典 - 面试题 17.13. 恢复空格(DP+Trie树)

發(fā)布時(shí)間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员面试金典 - 面试题 17.13. 恢复空格(DP+Trie树) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 動(dòng)態(tài)規(guī)劃
      • 2.2 Trie樹

1. 題目

哦,不!你不小心把一個(gè)長篇文章中的空格、標(biāo)點(diǎn)都刪掉了,并且大寫也弄成了小寫。
像句子"I reset the computer. It still didn’t boot!"已經(jīng)變成了"iresetthecomputeritstilldidntboot"。
在處理標(biāo)點(diǎn)符號(hào)和大小寫之前,你得先把它斷成詞語。
當(dāng)然了,你有一本厚厚的詞典dictionary,不過,有些詞沒在詞典里。
假設(shè)文章用sentence表示,設(shè)計(jì)一個(gè)算法,把文章斷開,要求未識(shí)別的字符最少,返回未識(shí)別的字符數(shù)。

注意:本題相對(duì)原題稍作改動(dòng),只需返回未識(shí)別的字符數(shù)

示例: 輸入: dictionary = ["looked","just","like","her","brother"] sentence = "jesslookedjustliketimherbrother" 輸出: 7 解釋: 斷句后為"jess looked just like tim her brother",共7個(gè)未識(shí)別字符。(jess tim)提示: 0 <= len(sentence) <= 1000 dictionary中總字符數(shù)不超過 150000。 你可以認(rèn)為dictionary和sentence中只包含小寫字母。

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/re-space-lcci
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

2. 解題

2.1 動(dòng)態(tài)規(guī)劃

  • dp[i] 表示包含 i 字符結(jié)尾的字符串 最少的未識(shí)別字符數(shù),初始為 i+1(全部未識(shí)別)
  • 將 [ 0, i ] 區(qū)間切分,[ 0, j-1 ],[ j, i ] ,遍歷所有的 j (j <= i)
  • 如果字典包含字符串 [ j, i ],dp[i]=min?(dp[i],dp[j?1])dp[i] = \min(dp[i], dp[j-1])dp[i]=min(dp[i],dp[j?1])
  • 如果字典不包含字符串 [ j, i ],dp[i]=min?(dp[i],dp[j?1]+i?j+1)dp[i] = \min(dp[i], dp[j-1]+i-j+1)dp[i]=min(dp[i],dp[j?1]+i?j+1)
  • 一旦 dp[i] == 0,可以終止內(nèi)層循環(huán)
class Solution { public:int respace(vector<string>& dictionary, string sentence) {if(sentence.empty())return 0;int i, j, n = sentence.size();unordered_set<string> s;vector<int> dp(n,INT_MAX);for(auto& d : dictionary)s.insert(d);for(i = 0; i < n; ++i){dp[i] = i+1;if(s.count(sentence.substr(0,i+1))){dp[i] = 0;continue;}for(j = i; j > 0; --j){if(s.count(sentence.substr(j,i-j+1)))dp[i] = min(dp[i], dp[j-1]);elsedp[i] = min(dp[i], dp[j-1]+i-j+1);if(dp[i]==0)break;}}return dp[n-1];} };

1156 ms 446.1 MB

2.2 Trie樹

  • 在上面的思路下,將字典字符串反向插入trie樹
  • 內(nèi)層循環(huán)可以改為向前在trie樹中查找存在的字符串最大長度,一旦不存在某個(gè)字符就不必再往前遍歷了,因?yàn)榭隙ú淮嬖?#xff0c;可以提高效率。
class trie { public:trie* cur;trie* next[26] = {NULL};bool isEnd = false;void insert(string& s){cur = this;for(int i = s.size()-1; i >= 0; --i)//反向插入{if(cur->next[s[i]-'a'] == NULL){cur->next[s[i]-'a'] = new trie();}cur = cur->next[s[i]-'a'];}cur->isEnd = true;} };class Solution { public:int respace(vector<string>& dictionary, string sentence) {if(sentence.empty())return 0;int i, j, n = sentence.size();unordered_set<string> s;trie *t = new trie(), *cur;for(auto& d : dictionary)t->insert(d);//字典插入trie樹vector<int> dp(n,INT_MAX);for(i = 0; i < n; ++i){dp[i] = i+1;cur = t;for(j = i; j >= 0; --j)//從i處向前在trie樹中查找單詞{ if(cur->next[sentence[j]-'a'])//下一個(gè)字符存在{if(cur->next[sentence[j]-'a']->isEnd)//且是結(jié)束位置{if(j > 0)dp[i] = min(dp[i], dp[j-1]);elsedp[i] = 0;}else//不是結(jié)束位置,不匹配{if(j > 0)dp[i] = min(dp[i], dp[j-1]+i-j+1);elsedp[i] = min(dp[i], i-j+1);}}else//下一個(gè)字符不存在,可以結(jié)束了{if(j > 0)dp[i] = min(dp[i], dp[j-1]+i-j+1);elsedp[i] = min(dp[i], i-j+1);break;}if(dp[i]==0) break;cur = cur->next[sentence[j]-'a'];}}return dp[n-1];} };

120 ms 153.8 MB


我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關(guān)注我的公眾號(hào)(Michael阿明),一起加油、一起學(xué)習(xí)進(jìn)步!

總結(jié)

以上是生活随笔為你收集整理的程序员面试金典 - 面试题 17.13. 恢复空格(DP+Trie树)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。