leecode刷题系列之763. 划分字母区间

想着靠leecode刷题来提升下自己,发现leecode好像不能查看以前做过的题目,所以还是自己写了保存下吧,以后想看的时候还能找到。

题目链接:763. 划分字母区间

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。

示例 1:

输入: S = "ababcbacadefegdehijhklij"
输出: [9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。

注意:

  1. S的长度在[1, 500]之间。
  2. S只包含小写字母'a''z'

一、解题思路

举例子说明来得更快,先定义一个结构体struct ord和结构体ord的容器vector<ord> co;

typedef struct coordiation{
    char word;
    int start;
    int end;
} ord;//存储字符word的最前一个位置和最后一个位置坐标

vector<ord> co;//结构体ord的容器

我们假如要分割的字符串为s="bbvemgjwruuwalp",我们把每一个不同字符的开始位置和结束位置找出来,一定是不同字符,记录进该字符对应的结构体,比如字符b的开始位置为0,结束位置为1,则b对应的结构体为{‘b’,0,1},我们将出现过的字符在原始字符串中置为字符0,这样就能保证每一个不同的字符在结构体容器co中只出现一次了。依次遍历原始字符串s中的每一个字符,将不同字符对应的结构体推入co中。

现在s="bbvemgjwruuwalp",则得到的结构体分别为(IDE为CLion):

 

 

得到了结构体co,也就清楚了每一个不重复字符的开始和结束位置,现在则合并那些有交集的字符并计算有交集字符的开始和结束位置。观察上面的co结构体,我们发现co[0]=b和co[1]=v是没有交集的(因为v.start>b.end),所以就有了字符串片段"bb",片段长度为end-start+1=1-0+1=2,再观察co[6]=w和co[7]=r,我们发现它们是交集的(因为r.start<w.end),而且w之间是包含r的,差不多是这种形式,r...w..r,所以要合并,合并后的start取两者较小的start(其实是不变的),合并后的end,则取较大的end。将所有有交集的字符进行合并,没有交集的字符则做为一个单独的片段。最后就可以计算出每一个片段的长度。我这里得到的结果是:

二、CLion代码(有一些帮助理解的注释)

#include <iostream>
#include <vector>

using namespace std;
typedef struct coordiation{
    char word;
    int start;
    int end;
} ord;//字符word的最前一个位置和最后一个位置坐标
//救出字符串S中每一个不重复字符的ord结构体
vector<ord> HaveCoordination(string &s){
    vector<ord> co;
    for(int i=0;i<s.length();i++){
        if('0'==s[i]) continue;
        ord temp;
        temp.word=s[i];//存储字符
        temp.start=i;//存储字符的开始位置
        int flag=0;//字符s[i]是否出现的标志
        for(int j=i+1;j<s.length();j++){
            if(s[i]==s[j]) {//如果遇到重复字符,则将字符的最后位置给temp并入容器,否则不给,也不入容器
                temp.end = j;
                s[j]='0';
                flag=1;
            }
        }
        if(0==flag){
            temp.end=i;
        }
        co.push_back(temp);
        s[i]='0';
    }
    return co;
};
//得到每个不同字母的坐标后,执行partitionLabels函数,返回
vector<int> partitionLabels(const vector<ord> &co) {
    vector<int> result;
    int start_temp=co[0].start;
    int end_temp=co[0].end;
    int result_temp=end_temp-start_temp;//每片不重复字符串的长度
    for(int i=1;i<co.size();i++){
        //如果i的start小于end_temp,就要合并两个长度
        if(co[i].start<=end_temp){
            if(co[i].end>end_temp) end_temp=co[i].end;
            result_temp=end_temp-start_temp;
            //continue;-var-create: unable to create variable object
        }
        //不然更新start_temp和end_temp
        else{
            result.push_back(result_temp+1);
            start_temp=co[i].start;
            end_temp=co[i].end;
            result_temp=end_temp-start_temp;
        }
    }
    result.push_back(result_temp+1);
    return result;
}
int main() {
    //std::cout << "Hello, World!" << std::endl;
    vector<ord> co_m;
    vector<int> result;
    string s="bbvemgjwruuwalp";
    co_m=HaveCoordination(s);
    result=partitionLabels(co_m);
    cout<<result[0]<<endl;
    return 0;
}

三、leecode代码

class Solution {
    typedef struct coordiation{
    char word;
    int start;
    int end;
    } ord;//字符word的最前一个位置和最后一个位置坐标
public:
//求出字符串S中每一个不重复字符的ord结构体
vector<ord> HaveCoordination(string &s){
    vector<ord> co;
    for(int i=0;i<s.length();i++){
        if('0'==s[i]) continue;
        ord temp;
        temp.word=s[i];//存储字符
        temp.start=i;//存储字符的开始位置
        int flag=0;//字符s[i]是否出现的标志
        for(int j=i+1;j<s.length();j++){
            if(s[i]==s[j]) {//如果遇到重复字符,则将字符的最后位置给temp并入容器,否则不给,也不入容器
                temp.end = j;
                s[j]='0';
                flag=1;
            }
        }
        if(0==flag){
            temp.end=i;
        }
        co.push_back(temp);
        s[i]='0';
    }
    return co;
};
//得到每个不同字母的坐标后,执行partitionLabels函数,返回
vector<int> partitionLabels(string &s) {
    vector<ord> co=HaveCoordination(s);
    
    vector<int> result;
    int start_temp=co[0].start;
    int end_temp=co[0].end;
    int result_temp=end_temp-start_temp;;//每片不重复字符串的长度
    for(int i=1;i<co.size();i++){
        //如果i的start小于end_temp,就要合并两个长度
        if(co[i].start<=end_temp){
            if(co[i].end>end_temp) end_temp=co[i].end;
            result_temp=end_temp-start_temp;
            //continue;
        }
        //不然更新start_temp和end_temp
        else{
            result.push_back(result_temp+1);
            start_temp=co[i].start;
            end_temp=co[i].end;
            result_temp=end_temp-start_temp;
        }
    }
    result.push_back(result_temp+1);
    return result;
}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值