力扣 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;
    }
};
相关推荐
hetao17338373 分钟前
2025-12-12~14 hetao1733837的刷题笔记
数据结构·c++·笔记·算法
椰子今天很可爱7 分钟前
五种I/O模型与多路转接
linux·c语言·c++
程序员zgh40 分钟前
C++ 互斥锁、读写锁、原子操作、条件变量
c语言·开发语言·jvm·c++
鲨莎分不晴1 小时前
强化学习第五课 —— A2C & A3C:并行化是如何杀死经验回放
网络·算法·机器学习
搞科研的小刘选手2 小时前
【ISSN/ISBN双刊号】第三届电力电子与人工智能国际学术会议(PEAI 2026)
图像处理·人工智能·算法·电力电子·学术会议
拉姆哥的小屋2 小时前
从混沌到秩序:条件扩散模型在图像转换中的哲学与技术革命
人工智能·算法·机器学习
Sammyyyyy2 小时前
DeepSeek v3.2 正式发布,对标 GPT-5
开发语言·人工智能·gpt·算法·servbay
sin_hielo2 小时前
leetcode 2110
数据结构·算法·leetcode
Jay20021113 小时前
【机器学习】33 强化学习 - 连续状态空间(DQN算法)
人工智能·算法·机器学习
panzer_maus3 小时前
归并排序的简单介绍
java·数据结构·算法