题目:
给定两个串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; }