剑指 Offer II 014. 字符串中的变位词

给定两个字符串 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 仅包含小写字母

解析1:

对s2使用一个长度为s1.length()的滑动窗口

class Solution {
public:
    bool checkInclusion(string s1, string s2) {

        vector<int> vis1(26, 0), vis2(26, 0);
        int n = s1.length();
        int m = s2.length();
        if(n > m) return false;
        for(int i = 0; i < n; i++)
        {
            vis1[s1[i] - 'a']++;
            vis2[s2[i] - 'a']++;
        }
        if(vis1 == vis2)
            return true;
        for(int i = n; i < m; i++)
        {
            vis2[s2[i - n] - 'a']--;
            vis2[s2[i] - 'a']++;
            if(vis1 == vis2)
                return true;
        }
        return false;
    }
};

 

 

解析2:

  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;


    }
};

 

  

posted @ 2022-04-04 23:12  WTSRUVF  阅读(31)  评论(0编辑  收藏  举报