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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

每天一道LeetCode-----给定字符串s和字符数组words,在s中找到words出现的位置,words内部字符串顺序无要求

發(fā)布時間:2024/4/19 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----给定字符串s和字符数组words,在s中找到words出现的位置,words内部字符串顺序无要求 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Substring with Concatenation of All Words

原題鏈接Substring with Concatenation of All Words

題目意思是給定字符串s和字符數(shù)組words,在s中尋找words出現(xiàn)的位置,words內(nèi)部的字符串順序沒有要求


此問題可以直接順序搜索,假設(shè)s的長度為m,words的長度為n,words中每個單詞的長度為w,復(fù)雜度是O((m-n*w)*n),需要利用兩個unordered_map<string,int>,一個記錄每個單詞總共需要多少個,一個記錄當(dāng)前遍歷到的單詞數(shù),如果遇到不在words中的單詞,就break從下一個開始找


另一種方法是使用滑動窗口,也是利用兩個unordered_map<string, int>。原理是當(dāng)不匹配是移動起始點,每一移動w個距離。不匹配有兩種情況

  • 當(dāng)前單詞不是words中的單詞,重新開始找,初始化負(fù)責(zé)記錄遍歷到的單詞數(shù)的那個map
  • 當(dāng)前單詞word是words中的單詞,但是這個單詞已經(jīng)夠了,不再需要這個單詞了。此時需要將窗口向右移動,直到出現(xiàn)第一個word為止,從這個word后面開始記錄
  • 舉個例子,

    s = "barfoobarfoothebar"; words = ["bar","bar","foo","the"];unordered_map<string, int> counts; /** 記錄每個單詞需要的次數(shù)* bar foo the* 2 1 1*/unordered_map<string, int> seen; /** 記錄當(dāng)前找到的單詞數(shù)* bar foo the* 0 0 0*/int count; /* 記錄當(dāng)前找到的單詞數(shù),0,目標(biāo)大小為words的大小,4 */int startIndex; /* 開始位置,0,找到就把它添加到結(jié)果的vector中 *//*1. 從s起點開始找,每3一判斷,第一個bar,"bar"是要找的單詞(在counts中),給seen對應(yīng)為加一,此時seen["bar"]=1, count=1;2. 接著找第二個單詞"foo",也在counts中,給seen對應(yīng)位加一,此時seen["foo"]=1, count=2;3. 繼續(xù)找"bar",也在counts中,給seen加一,此時seen["bar"]=2,count=3;4. 繼續(xù)找"foo",也在counts中,給seen加一,此時seen["foo"]=2,但是counts["foo"]=1,表示"foo"只需要一個,此時不滿足條件,移動1. 從startIndex開始刪除單詞,直到找到第一個"foo"2. 刪掉"bar",此時seen["bar"]=1,count=1,startIndex=0+3=3;3. 刪掉"foo",此時seen["foo"]=1,不改變count,因為當(dāng)不滿足時,沒有增加count,startIndex=6;4. 找到第一個"foo"了,繼續(xù)查找單詞5. 繼續(xù)找"the",在counts中,給seen加一,此時seen["the"]=1,count=26. ...7. 最終找到count==n,將startIndex=6添加到結(jié)果中8. 再右移一個單詞,刪掉"bar",此時seen["bar"]=1,count=3,startIndex=99. 繼續(xù)尋找10. ...11. 遇到單詞"abc",不在counts中,重置seen,count,startIndex12. 繼續(xù)尋找13. ...14. 結(jié)束*/

    代碼如下

    class Solution { public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> res;if(s.size() == 0 || words.size() == 0)return res;unordered_map<string, int> dict;for(auto &str : words)++dict[str];int n = s.size();int cnt = words.size();int wl = words[0].size();/* * 每個單詞長度為wl,那么只需要循環(huán)wl次,每次移動wl個為* 0, wl, 2*wl, 3*wl ...* 1, 1+wl, 1+2*wl, 1+3*wl...* 2, 2+wl, 2+2*wl, 2+3*wl...* ...*/for(int i = 0; i < wl; ++i){int left = i;int count = 0;unordered_map<string, int> tdict; //seen/* 每次移動wl個 */for(int j = i; j <= n - wl; j+=wl){string str = s.substr(j, wl);/* 如果是需要的單詞,就添加到seen中 */if(dict.count(str)){tdict[str]++;/* 如果已經(jīng)不需要了,就不用增加count */if (tdict[str] <= dict[str]) count++;else{/* 如果當(dāng)前這個單詞是多余的,超出了數(shù)量限制,就移動窗口 */while (tdict[str] > dict[str]) {string str1 = s.substr(left, wl);tdict[str1]--;/* 因為多余的那個單詞沒有增加count,所以也不需要減count */if (tdict[str1] < dict[str1]) count--;left += wl;}}/* 如果到所有,右移 */if (count == cnt) {res.push_back(left);// advance one wordtdict[s.substr(left, wl)]--;count--;left += wl;}}/* 不是需要的單詞,重置所有 */else{tdict.clear();count = 0;left = j + wl;}}}return res;} };

    啊啊啊啊下午的心情一點也不好-.-

    總結(jié)

    以上是生活随笔為你收集整理的每天一道LeetCode-----给定字符串s和字符数组words,在s中找到words出现的位置,words内部字符串顺序无要求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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