力扣 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;
    }
};
相关推荐
ragnwang20 分钟前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习
火星机器人life2 小时前
基于ceres优化的3d激光雷达开源算法
算法·3d
虽千万人 吾往矣2 小时前
golang LeetCode 热题 100(动态规划)-更新中
算法·leetcode·动态规划
arnold663 小时前
华为OD E卷(100分)34-转盘寿司
算法·华为od
ZZTC3 小时前
Floyd算法及其扩展应用
算法
lqqjuly3 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
lshzdq3 小时前
【机器人】机械臂轨迹和转矩控制对比
人工智能·算法·机器人
冰红茶兑滴水4 小时前
云备份项目--工具类编写
linux·c++
刘好念4 小时前
[OpenGL]使用 Compute Shader 实现矩阵点乘
c++·计算机图形学·opengl·glsl
2401_858286114 小时前
115.【C语言】数据结构之排序(希尔排序)
c语言·开发语言·数据结构·算法·排序算法