链接:https://www.nowcoder.com/acm/contest/161/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。
输入描述:
一行一个字符串S。只包含小写字母。S的长度不超过106
.
输出描述:
一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。
示例1
输出
复制49
思路:设置两个指针,左右放缩。
#include <iostream>
#include <cstring>
using namespace std;
int a[26];
int main(){
string str;
cin >> str;
int len = str.length();
int i = 0, j = 0, ct = 0, ans = 0x3f3f3f3f;
while(i < len){
if(a[str[i] - 'a'] == 0)
ct++;
a[str[i] - 'a']++;
while(a[str[j] - 'a'] > 1){
a[str[j] - 'a']--, j++;
}
if(ct == 26 && i - j + 1 < ans)
ans = i - j + 1;
i++;
}
cout << ans << endl;
return 0;
}
下面这种没过,还不知道原因!!!
#include <iostream>
#include <cstring>
#include <map>
#include <set>
using namespace std;
int main(){
string str;
cin >> str;
int left = 0, right = 0;
map<char, int> mymap;
set<char> myset;
for(int i = 0; i < 26; i++){
mymap['a' + i] = 0;
}
int len = str.length(), minsize = 0x3f3f3f3f;
int ct = 0;
while(left < len && right < len + 1){
if(myset.size() >= 26){
mymap[str[left]]--; //左边踢一个
if(mymap[str[left]] == 0){
myset.erase(str[left]);
// cout << str[left] << "--------------" << endl;
}
else{
int r = right >= len ? len - 1 : right;
if(minsize > r - left){
minsize = r - left + 1 - 1; //踢掉了一个
}
}
left++;
}
else{
if(right >= len)
break;
if(myset.count(str[right]) == 0){
ct++;
myset.insert(str[right]);
if(myset.size() >= 26 && minsize > right - left + 1){
minsize = right - left + 1;
}
}
mymap[str[right]]++;
right++;
}
}
cout << minsize << endl;
return 0;
}