校招算法笔面试 | 校招笔面试真题-字符串分割

题目

题目链接

题解:

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

方法一:暴力

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

#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;j<len;j++){" if(s[i]="=s[j])" end="j;" } }else{ v.push_back(end-start+1); start="i,End=i;" if(s[j]="=s[i])" i="0;i<v.size();i++){" if(i="=v.size()-1)" printf("%d\n",v[i]); else printf("%d ",v[i]); return 0; ```**方法二:区间合并** 更进一步,可以对上述方法做出优化。设置两个数组$l$和$r$,分别记录每个字母在字符串中的开始位置和结束位置。其余流程跟方法一相同,这样在维护每个字母的开始位置和结束位置时,不用对整个字符串做遍历,通过空间换时间的方法,将时间复杂度降到$o(n)$ ```cpp #include "bits stdc++.h" using namespace std; const int maxn="30;" l[maxn],r[maxn]; string s; main() { memset(l,-1,sizeof(l)); memset(r,-1,sizeof(r)); cin>&gt;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;" } 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</len;i++){></len;i++){></len;i++){></len;i++){>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值