NC18386—字符串(双指针/尺取法)
链接:https://ac.nowcoder.com/acm/problem/18386链接:https://ac.nowcoder.com/acm/problem/18386
题目描述
小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。
输入描述:
一行一个字符串S。只包含小写字母。S的长度不超过106.
输出描述:
一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。
#include<iostream> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int N=1e6+50; string s; int ans=N,cnt[26]; //用cnt数组储存查询情况,有一个为0都表示不包含所有小写字母 bool judge() //此函数循环遍历cnt,判断是否有所有小写字母 { for(int i=0;i<26;i++) if(cnt[i]==0) return false; return true; } void solve() { cin>>s; //输入一个待测字符串 int l=0,r=0; //双指针l和r用来移动控制判断 for(;l<s.size();l++) //外层左界循环,内层右界循环 { while(r<s.size()&&!judge()) { cnt[s[r]-'a']++; r++; } if(judge()) { cnt[s[l]-'a']--; ans=min(ans,r-l); } } cout<<ans<<endl; } int main() { ios::sync_with_stdio(false); cin.tie(0); solve(); return 0; }
l在外层循环,r在内层循环:r循环到满足条件的地方,更新ans,r不动,l往右移动看是否满足,若满足则更新ans,否则r继续移动到下一个满足条件的地方,以此类推只到字符串结尾。
算法入门基础 文章被收录于专栏
Dawn的算法入门