题目
牛牛有个很喜欢的字符串 "puleyaknoi"。
牛牛有 T 个很长很长的字符串,他很喜欢把字符串中的子串(连续的某段)打乱,并且按照自己的喜好重新排列。
如果牛牛能把一段重新排列出他喜欢的字符串,他就会把这个子串称作:喜欢的子串。
求出对于每个字符串,最短的喜欢的子串的长度是多少?
如果没有,请输出-1。
解题思路
双指针 + 滑动窗口
如果区间 [i, j] 内的字符串能排列成喜欢的字符串,向右移动 i,否则向右移动 j。
C++代码
#include<iostream> #include<cstring> using namespace std; int like[26] = {0}; int tmp[26]={0}; string str = "puleyaknoi"; inline bool check(){ for(int i=0; i<26; ++i){ if(tmp[i]<like[i]) return false; } return true; } int main(){ int T; string s; for(auto c : str){ int i = c - 'a'; like[i] += 1; } cin >> T; while(T--){ cin >> s; memset(tmp, 0, sizeof(tmp)); int ans = -1; int i=0, j=0; tmp[s[0]-'a'] += 1; while(j<s.size()){ if(check()){ if(ans == -1) ans = j-i+1; else ans = min(ans, j-i+1); tmp[s[i]-'a']-=1; ++i; } else{ ++j; if(j==s.size()) break; tmp[s[j]-'a']+=1; } } cout << ans << endl; } return 0; }