力扣 763. 划分字母区间

题目来源:https://leetcode.cn/problems/partition-labels/description/

C++题解1: 先遍历一遍使用哈希算法找到每个小写字母的最远的索引,再遍历一次,不断更新每个片段的最远距离。

cpp 复制代码
class Solution {
public:
    vector<int> partitionLabels(string s) {
        int len = s.size();
        vector<int> inds(26, 0);
        for(int i = 0; i < len; i++){
            int ind = s[i] - 'a';
            inds[ind] = i;
        }
        vector<int> res;
        for(int j = 0; j < len; j++){
            int count = 1;
            int end = inds[s[j] - 'a'];
            if(j == end) res.push_back(count);
            else {
                for(int k = j+1; k <= end; k++) {
                    end = max(end, inds[s[k] - 'a']);
                }
                count = end - j + 1;
                res.push_back(count);
                j = end;
            }
        }
        return res;
    }
};

C++题解2(来源代码随想录):记录每个字母开始与结束的索引,用不重复区间的方式解题。将区间按左边界从小到大排序,找到边界将区间划分成组,互不重叠。找到的边界就是答案。

cpp 复制代码
class Solution {
public:
    static bool cmp(vector<int> &a, vector<int> &b) {
        return a[0] < b[0];
    }
    // 记录每个字母出现的区间
    vector<vector<int>> countLabels(string s) {
        vector<vector<int>> hash(26, vector<int>(2, INT_MIN));
        vector<vector<int>> hash_filter;
        for (int i = 0; i < s.size(); ++i) {
            if (hash[s[i] - 'a'][0] == INT_MIN) {
                hash[s[i] - 'a'][0] = i;
            }
            hash[s[i] - 'a'][1] = i;
        }
        // 去除字符串中未出现的字母所占用区间
        for (int i = 0; i < hash.size(); ++i) {
            if (hash[i][0] != INT_MIN) {
                hash_filter.push_back(hash[i]);
            }
        }
        return hash_filter;
    }
    vector<int> partitionLabels(string s) {
        vector<int> res;
        // 这一步得到的 hash 即为无重叠区间题意中的输入样例格式:区间列表
        // 只不过现在我们要求的是区间分割点
        vector<vector<int>> hash = countLabels(s);
        // 按照左边界从小到大排序
        sort(hash.begin(), hash.end(), cmp);
        // 记录最大右边界
        int rightBoard = hash[0][1];
        int leftBoard = 0;
        for (int i = 1; i < hash.size(); ++i) {
            // 由于字符串一定能分割,因此,
            // 一旦下一区间左边界大于当前右边界,即可认为出现分割点
            if (hash[i][0] > rightBoard) {
                res.push_back(rightBoard - leftBoard + 1);
                leftBoard = hash[i][0];
            }
            rightBoard = max(rightBoard, hash[i][1]);
        }
        // 最右端
        res.push_back(rightBoard - leftBoard + 1);
        return res;
    }
};
相关推荐
CoovallyAIHub5 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
感哥5 小时前
C++ STL 常用算法
c++
CoovallyAIHub5 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
saltymilk16 小时前
C++ 模板参数推导问题小记(模板类的模板构造函数)
c++·模板元编程
感哥16 小时前
C++ lambda 匿名函数
c++
沐怡旸1 天前
【底层机制】std::unique_ptr 解决的痛点?是什么?如何实现?怎么正确使用?
c++·面试
感哥1 天前
C++ 内存管理
c++
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法