【LeetCode763】-划分字母区间

方法一

实现思想

首先要理解子片段是怎么定义的,子片段保证里面含有的字母仅出现在该子片段中,也就是不同子片段之间字母是没有交集的

利用了【LeetCode392】-判断子序列拓展题目的思想,提前存储了字符串中各个字母出现的初位置和末位置
利用了 【LeetCode452】-用最少数量的箭引爆气球 不同区间更换弓箭手的思想,当两个区间有重叠时,更新区间,当两个区间没有重叠时,将当前结果压入,更新区间的范围为新区间的范围

概括来说就是遍历求得每一种字母在字符串中起始结束位置,按照起始位置将数据升序排列,遍历该预处理的数组,进行区间合并,压入结果时压入的是区间的初末位置的长度

实现代码

bool cmp(const vector<int> &a,const vector<int> &b){
    
    
    return a[0]<b[0];
}
class Solution {
    
    
public:
    vector<int> partitionLabels(string S) {
    
    
            vector<vector<int>> ab;
            vector<int> book(26,-1);
            for(int i=0;i<S.length();i++){
    
    
                int t=S[i]-'a';
                if(book[t]==-1){
    
    
                    vector<int> tt;
                    tt.push_back(i);
                    tt.push_back(i);
                    int nn=ab.size();
                    book[t]=nn;
                    ab.push_back(tt);
                }
                else{
    
    
                    ab[book[t]][1]=i;
                }
            }
            sort(ab.begin(),ab.end(),cmp);
            vector<int> res;
            int be=ab[0][0];
            int end=ab[0][1];
            for(int i=1;i<ab.size();i++){
    
    
                if(ab[i][0]<end) end=max(end,ab[i][1]);
                else{
    
    
                    res.push_back(end-be+1);
                    be=ab[i][0];
                    end=ab[i][1];
                }
            }
            res.push_back(end-be+1);
            return res;
    }
};

提交结果及分析

在这里插入图片描述
时间复杂度O(n),空间复杂度O(n)

方法二

实现思想

提前存储所有字母出现的最后一个位置,i开始遍历字符串,里面i所经历过的字母如果可以扩充end值则进行扩充来更新end值,当i等于end时说明这一子序列遍历完毕,然后更新start=end+1

实现代码

在这里插入图片描述在这里插入图片描述

与我的方法一不同的一点在于,并没有记录出现的第一个位置,而是只记录了最后的一个位置

分析

时间复杂度O(n)

猜你喜欢

转载自blog.csdn.net/weixin_44944046/article/details/113801246