题目传送
题意:
给你一个只由1 2 3这三个数字组成的字符串,现在要求你求出其中包含1 2 3的子串(这个子串指的是连续的字符串片段),问:这个满足条件的子字符串最短的长度为多少,如果不存在输出0.
思路:
很明显,要求最短,那么在这个字符串中,我们先一个for从第一个位置开始找,然后我们取每一种数的最大的位置(可以使得,存在这三种数的字符串压缩到最短),当三个数在遍历的过程中,都存在了(现在寻找的字符串已经满足了存在1 2 3),那么更新最小值。
说得糊里糊涂的。。。。。看代码,很容易懂,没多少行
AC代码
#include <bits/stdc++.h>
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
const int N = 5e5 + 5;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const unsigned long long mod = 998244353;
const double II = 3.1415926535;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t;
cin >> t;
while(t--)
{
string s;
cin >> s;
int vis1 = -1,vis2 = -1,vis3 = -1,Min = INF;
//-1代表暂时没有存在
for(int i = 0;i < s.size();i++)
{
if(s[i] == '1') vis1 = max(vis1,i);
if(s[i] == '2') vis2 = max(vis2,i);
if(s[i] == '3') vis3 = max(vis3,i);
//取这个数最右边的位置,可以使得前面重复删去
//如:11111223,那么我们取到的1把左边无用的去掉了
if(vis1 != -1 && vis2 != -1 && vis3 != -1)
{
int a = max(vis1,max(vis2,vis3)),b = min(vis1,min(vis2,vis3));//这个是为了算子字符串的长度
Min = min(Min,a-b+1);//更新最小值
}
}
if(Min == INF) cout << 0 << endl;//不存在
else cout << Min << endl;
}
}