字符串分割

字符串分割

http://www.nowcoder.com/questionTerminal/8b870ea5dda44975a08f4b82fd6bdb16

题解:

考察点: 区间合并,双指针

方法一:暴力

一般来说,暴力都是解决问题最直观,也是最容易被同学们想到的方法。题中明确说明每个字母只能在一个子串中出现,因此必须保证子串内的每个字母在字符串中第一次出现的位置到最后一次出现的位置都位于区间中。设置两个指针,表示区间的开始位置和结束位置。当访问到字符串中位置时,如果不超过,则比较在字符串中结束位置和的大小,如果大于,则把修改为的结束位置;如果大于,则记录区间的长度。因为对于每个位置都需要向后找寻结束位置,一共有个位置需要找寻,时间复杂度是

#include "bits/stdc++.h"
using namespace std;
string s;
int main()
{
    cin>>s;
    int len=s.length();
    int Start=0,End=0;
    for(int i=0;i<len;i++){
        if(s[i]==s[0]) End=i;
    }
    vector<int>v;
    for(int i=0;i<len;i++){
        if(i<=End){
            for(int j=i+1;j<len;j++){
                if(s[i]==s[j]) End=max(End,j);
            }
        }else{
            v.push_back(End-Start+1);
            Start=i,End=i;
            for(int j=i;j<len;j++){
                if(s[j]==s[i]) End=j;
            }
        }
    }
    v.push_back(End-Start+1);
    for(int i=0;i<v.size();i++){
        if(i==v.size()-1) printf("%d\n",v[i]);
        else printf("%d ",v[i]);
    }
    return 0;
}

方法二:区间合并

更进一步,可以对上述方法做出优化。设置两个数组,分别记录每个字母在字符串中的开始位置和结束位置。其余流程跟方法一相同,这样在维护每个字母的开始位置和结束位置时,不用对整个字符串做遍历,通过空间换时间的方法,将时间复杂度降到

#include "bits/stdc++.h"
using namespace std;
const int maxn=30;
int l[maxn],r[maxn];
string s;
int main()
{
    memset(l,-1,sizeof(l));
    memset(r,-1,sizeof(r));
    cin>>s;
    int len=s.length();
    for(int i=0;i<len;i++){
        int tmp=s[i]-'a';
        if(l[tmp]==-1){
            l[tmp]=i,r[tmp]=i;
        }else{
            r[tmp]=i;
        }
    }
    int Start=l[s[0]-'a'],End=r[s[0]-'a'];
    vector<int>v;
    for(int i=0;i<len;i++){
        int tmp=s[i]-'a';
        if(i>End){
            v.push_back(End-Start+1);
            Start=i;
            End=r[tmp];
        }else{
            End=max(End,r[tmp]);
        }
    }
    v.push_back(End-Start+1);
    for(int i=0;i<v.size();i++){
        if(i==v.size()-1) printf("%d\n",v[i]);
        else printf("%d ",v[i]);
    }
    return 0;
}
全部评论

相关推荐

评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务