(字符串)子串变位词

题目:

给定两个串a和b,问b是否是a的子串的变位词,例如输入a=hello,b=lel,lle,ello都是true,但b=elo是false。(字串是连续的)

思路:

  • 滑动窗口思想:动态维护一个“窗口”,比如b的长度是3,考察a[0..2],a[1..3],a[2..4]是否是b的变位词,关键在于如何与b比较?
  • hash数组统计:基于字符的特殊性,可以用[0,255]的数组来统计字符出现的次数,假设都是小写的英文字母,则用[0,25]来表示b中每个单词出现的次数,通过记录非0次出现的个数nonZero。
  • 窗口滑动,向右移动一位:

          新窗口 a[i-lenb+1…i],旧窗口 a[i-lenb…i-1]

          每次新窗口扔掉a[i-lenb],加入a[i]

#include <iostream>
#include<vector>
#include<string>
using namespace std;

bool variable_bit_word(string a,string b){
        int lena = a.size(),lenb=b.size();
        //首先把b存入数组
        vector<int> cnt(26);
        int nonzero = 0;
        for(int i=0;i<lenb;i++){
            int c = b[i]-'a';
            cnt[c]++;
            if(cnt[c] == 1) nonzero++;
        }
        //a的第一个窗口,长度lenb
        for(int i=0;i<lenb;i++){
            int c = a[i] -'a';
            cnt[c]--;
            if(cnt[c] == 0) nonzero--;
            if(cnt[c] == -1) nonzero++;
        }
        if(nonzero == 0) return true;
        //剩下的窗口,i是a窗口中最后一个字符位置
        for(int i=lenb;i<lena;i++){
            //去掉a[i-lenb],加上a[i]
            int c = a[i-lenb] - 'a';
            cnt[c]++;
            if(cnt[c] == 0) nonzero--;
            if(cnt[c] == 1) nonzero++;
            
            c = a[i]-'a';
            cnt[c]--;
            if(cnt[c] == 0) nonzero--;
            if(cnt[c] == -1) nonzero++;
            if(nonzero == 0) return true;
        }
        return false;
}
    
int main() {
    string a = "hello";
    string b = "lol";
    cout<<variable_bit_word(a,b);
    return 0;
}
原文地址:https://www.cnblogs.com/wsw-seu/p/13622365.html