(扫描线)lintcode中等1379 · 最长场景

题目

描述
一个字符串,每个字符表示一个场景。两个相同字符之间认为是一个连续的场景。例如: 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个区间这个思想
差分思想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

White boy&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值