题目
描述
一个字符串,每个字符表示一个场景。两个相同字符之间认为是一个连续的场景。例如: abcda,可以认为这五个字符是同一个场景。或者acafghbeb可以认为又aca和beb两个场景。场景之间有重合那么就把场景合起来,例如abcab,这里abca和bcab是重合的,那么认为这五个字符是同一个场景。给一个字符串,求最长场景。
提示
1 <= |str| <=1e5
str只包含小写字母
样例
样例1
输入: "abcda"
输出: 5
说明:
最长连续场景是 "abcda".
样例2
输入: "abcab"
输出: 5
说明:
最长连续场景是 "abcab".
分析
解读题意,给定一个字符串str,寻找最长场景,什么是场景,两个相同相同字符加上中间的字符串,以及中间字符串每个字符组成的场景,例如aba是场景,bacb是场景,abacb也是场景,因为b在aba中而b又可以组成bacb
题目中说明字符串由小写字母组成,那我们需要判断的区间最多只有26个,因为小写字母只有26个,而每个字母我们只需要找最长的区间,例如abaca,对于a来说我们只需要最长的那个,小的对于我们来说是没有意义的
我们只需要记录每个字母的最长区间左右端点的位置,然后在从头判断这个区间中的所有字符组成的场景,从而得出最大的场景长度
代码部分
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int getLongestScene(string &str) {
pair<int,int> sum[100]; //26个字母,最多26个区间
for(int i=0;i<26;i++) //初始化
{
sum[i].first=0xffffff;
sum[i].second=-1;
}
for(int i=0;i<str.size();i++) //扫描线
{
int index=str[i]-'a';
sum[index].first=min(sum[index].first,i);
sum[index].second=max(sum[index].second,i);
}
sort(sum,sum+26);
int l=sum[0].first;
int r=sum[0].second;
int ans= r==-1?0:r-l+1;
for(int i=1;i<26;i++)
{
if(sum[i].first<r) //重合的区间
{
if(sum[i].second!=-1) //有意义的区间
{
r=max(r,sum[i].second);
}
}
else //判断下一个区间
{
l=sum[i].first;
r=sum[i].second;
}
ans=max(ans,r-l+1);
}
return ans;
}
};
int main (void)
{
string str="abcab";
Solution s;
cout<<s.getLongestScene(str);
return 0;
}
总结
本题的难点在于把给定的字符串抽象成数组,还有就是只需要判断最多26个区间这个思想
差分思想