劍指 Offer II 014. 字串中的變位詞
阿新 • • 發佈:2022-04-05
給定兩個字串 s1 和 s2,寫一個函式來判斷 s2 是否包含 s1 的某個變位詞。
換句話說,第一個字串的排列之一是第二個字串的 子串 。
示例 1:
輸入: s1 = "ab" s2 = "eidbaooo"
輸出: True
解釋: s2 包含 s1 的排列之一 ("ba").
示例 2:
輸入: s1= "ab" s2 = "eidboaoo"
輸出: False
提示:
1 <= s1.length, s2.length <= 104
s1 和 s2 僅包含小寫字母
解析:
vis記錄s1中每個字母出現的次數
遍歷s2,如果遇到一個s1中的字母temp,vis1[temp]++,即vis1用來記錄當前所遇到的s1中相應字母的個數
如果vis1[temp] >= vis[temp],說明當前位置i的字母出現多了,那麼就刪去第一次出現的temp
試想 如果刪去了第一次出現的temp,那麼這個連續子串就中斷了,所以從這個連續子串開始的位置到第一次出現temp的位置的字母都要刪去
更新子串開始位置為第一次出現temp位置的下一個位置
二維queue記錄每個字母的出現位置
刪去的時候,相應的queue pop就可以,即更新每個字母第一次出現的位置
class Solution { public: bool checkInclusion(string s1, string s2) {int vis[30], vis1[30]; memset(vis, 0, sizeof(vis)); queue<int> q[30]; memset(vis1, 0, sizeof(vis1)); int len1 = s1.length(); for(int i = 0; i < len1; i++) { vis[s1[i] - 'a']++; } int ans = len1, cnt = 0, len2 = s2.length(), start;for(int i = 0; i < len2; i++) { if(cnt == ans) { return true; } int temp = s2[i] - 'a'; if(vis[temp]) { if(vis1[temp] >= vis[temp]) { int ll = q[temp].front(); for(int j = start; j <= ll; j++) vis1[s2[j] - 'a']--, cnt--, q[s2[j] - 'a'].pop(); start = ll + 1; } if(cnt == 0) start = i; vis1[temp]++, cnt++; q[temp].push(i); } else { for(int j = 0; j < 30; j++) while(!q[j].empty()) q[j].pop(); memset(vis1, 0, sizeof(vis1)); cnt = 0; } } return cnt == ans ? true : false; } };