链接: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; }