030串聯所有單詞並匹配

2022-06-04 12:09:07 字數 2794 閱讀 7572

1 #include "

000庫函式.h"2

3//自解;4

//這道題 的突破口就是找到words的組合情況5//

然後將所有組合一一查詢是否存在子串,還要對答案去重、查詢相同子串不同位置出現!!!6//

超出時間限制^_^,悲催,做了乙個小時

7class

solution 24}

25res.assign(r.begin(), r.end());

26return

res;

2728}29

3031

void swap(vector& words, int k, int

i) 37

38void permutation(vector&v, vector&words,int k, int m)//

使用遞迴對words進行全排列

3949

else

5057}58

}596061

};62

63//

部落格答案

64//

這道題我們需要用到兩個雜湊表,第乙個雜湊表先把所有的單詞存進去,

65//

然後從開頭開始乙個個遍歷,停止條件為當剩餘字元個數小於單詞集裡所有字元的長度。

66//

這時候我們需要定義第二個雜湊表,然後每次找出給定單詞長度的子串,看其是否在第乙個雜湊表裡,

67//

如果沒有,則break,如果有,則加入第二個雜湊表,但相同的詞只能出現一次,如果多了,也break。

68//

如果正好匹配完給定單詞集裡所有的單詞,則把i存入結果中,具體參見**如下:

69//

400ms

7071

class

solution

88if (j ==n) res.push_back(i);89}

90return

res;91}

92};

9394

//這道題還有一種o(n)時間複雜度的解法,設計思路非常巧妙,但是感覺很難想出來,博主目測還未到達這種水平。

95//

這種方法不再是乙個字元乙個字元的遍歷,而是乙個詞乙個詞的遍歷,比如根據題目中的例子,字串s的長度n為18,

96//

words陣列中有兩個單詞(cnt = 2),每個單詞的長度len均為3,那麼遍歷的順序為0,3,6,8,12,15,

97//

然後偏移乙個字元1,4,7,9,13,16,然後再偏移乙個字元2,5,8,10,14,17,這樣就可以把所有情況都遍歷到,

98//

我們還是先用乙個雜湊表m1來記錄words裡的所有詞,然後我們從0開始遍歷,用left來記錄左邊界的位置,

99//

count表示當前已經匹配的單詞的個數。然後我們乙個單詞乙個單詞的遍歷,如果當前遍歷的到的單詞t在m1中存在,

100//

那麼我們將其加入另乙個雜湊表m2中,如果在m2中個數小於等於m1中的個數,那麼我們count自增1,如果大於了,

101//

那麼需要做一些處理,比如下面這種情況, s = barfoofoo, words = , 我們給words中新加了乙個abc,

102//

目的是為了遍歷到barfoo不會停止,那麼當遍歷到第二foo的時候, m2[foo] = 2, 而此時m1[foo] = 1,這是後已經不連續了,

103//

所以我們要移動左邊界left的位置,我們先把第乙個詞t1 = bar取出來,然後將m2[t1]自減1,如果此時m2[t1] < m1[t1]了,

104//

說明乙個匹配沒了,那麼對應的count也要自減1,然後左邊界加上個len,這樣就可以了。如果某個時刻count和cnt相等了,

105//

說明我們成功匹配了乙個位置,那麼將當前左邊界left存入結果res中,此時去掉最左邊的乙個詞,同時count自減1,

106//

左邊界右移len,繼續匹配。如果我們匹配到乙個不在m1中的詞,那麼說明跟前面已經斷開了,我們重置m2,count為0,

107//

左邊界left移到j + len,參見**如下:

108109

110//

此解法牛逼,80ms

111112

class

solution ;

116 vectorres;

117int n = s.size(), cnt = words.size(), len = words[0

].size();

118 unordered_mapm1;

119for (string w : words) ++m1[w];

120for (int i = 0; i < len; ++i)

130else

137}

138if (count == cnt)

144}

145else

150}

151}

152return

res;

153}

154};

155156

void

t030() ;

159 vectorres;

160solution sol;

161 res =sol.findsubstring(s, words);

162for

(auto i : res)

163 cout << i <164165 }

30 串聯所有單詞的子串

本文參考 一開始的思路是使用遞迴做出words所有結合情況的字典 然後在s中擷取words長度去查字典 結果超時了 超時 class solution for int i 0 i chang i return vectorfindsubstring string s,vector words vec...

30 串聯所有單詞的子串

給定乙個字串 s 和一些長度相同的單詞words。找出s中恰好可以由words中所有單詞串聯形成的子串的起始位置。注意子串要與words中的單詞完全匹配,中間不能有其他字元,但不需要考慮words中單詞串聯的順序。輸入 s barfoothefoobarman words foo bar 輸出 0,...

30 串聯所有單詞的子串

給定乙個字串s和一些長度相同的單詞words。找出s中恰好可以由words中所有單詞串聯形成的子串的起始位置。注意子串要與words中的單詞完全匹配,中間不能有其他字元,但不需要考慮words中單詞串聯的順序。示例 1 輸入 s barfoothefoobarman words foo bar 輸出...