【代码随想录day 30】 力扣 763. 划分字母区间

视频讲解:https://www.bilibili.com/video/BV18G4y1K7d5/?vd_source=a935eaede74a204ec74fd041b917810c

文档讲解:https://programmercarl.com/0763.划分字母区间.html#思路

力扣题目:https://leetcode.cn/problems/partition-labels/

这道题我也做出来了,但是思想很麻烦:

  1. 统计多少字母并且其起始位置
  2. 按起始顺序升序排列
  3. 找到第一个存在的数组开始遍历,如果和前一个有交集,upper取max。
  4. 如果没有交集,upper即为截断点,lower和upper更新。

但是卡哥的思想就很简洁,不用考虑起始位置,只需要考虑右边界的最大值即可,

  1. 每次遍历取最大值的右边界

  2. 如果i 遍历到了右边界就说明该截断了,这里很精妙***

  3. 存入截断值,更新left,right在每次更新数的时候会更新,所以不用更新

cpp 复制代码
class Solution {
public:

    vector<int> partitionLabels(string s) {
       int hash[27] = {0};
       vector<int> result;

       //遍历字符串统计最远值
       for(int i = 0; i < s.size(); ++i)
       {
            hash[s[i] - 'a'] = i;
       }

        //初始化左右边界
        int left = 0;
        int right = 0;
       for(int i = 0; i < s.size(); ++i)
       {
            //每次遍历取右边界最大值
            right = max(right, hash[s[i] - 'a']);

            //如果遍历到最大值时候说明该截断了
            if(i == right)
            {
                result.push_back(right - left + 1);
                left = i + 1;
                //right = hash[i];
            }
       }
       return result;
    }
};

这里是我的代码,虽然可以运行但是比较繁琐随便参考一下好了

cpp 复制代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        // if(a[0] == b[0]);
        // 按起始位置升序排序
        return a[0] < b[0];
    }
    vector<int> partitionLabels(string s) {
        vector<vector<int>> index(26, vector<int>(2, -1));
        vector<int> result;
        // 遍历字符串s,统计其有什么字母以及字母的起始位置
        for (int i = 0; i < s.size(); ++i) {
            // 如果index中的第i个元素的起始位置为-1,说明还没有统计过这个字母的起始位置,将起始位置设为i
            if (index[s[i] - 'a'][0] == -1) {
                index[s[i] - 'a'][0] = i;
            }
            // 将该字符的终止位置更新为i
            index[s[i] - 'a'][1] = i;
        }
        // 将index按起始位置排序
        sort(index.begin(), index.end(), cmp);
        int start = 0;
        int lower;
        int upper;
        if (index[0][0] != -1) {
            lower = index[0][0];
            upper = index[0][1];
        }
        /*
        for(int i = 1; i < index.size(); ++i)
        {
            cout << index[i][0] << ' ' << index[i][1] << endl;
        }
        */
        for (int i = 1; i < index.size(); ++i) {
            // 如果找到第一个不是-1的数组
            if (index[i][0] != -1 && index[i - 1][0] == -1) {
                lower = index[i][0];
                upper = index[i][1];
            }
            // 如果该数组存在且起始位跟上一个有交集,扩大upper取max
            if (index[i][0] != -1 && index[i][0] < upper) {
                upper = max(upper, index[i][1]);
            }
            // 如果该数组起始位没有交集,存入切割点,更新lower和upper
            if (index[i][0] > upper) {
                result.push_back(upper - lower + 1);
                lower = index[i][0];
                upper = index[i][1];
            }
            if (i == index.size() - 1) {
                result.push_back(upper - lower + 1);
            }
        }

        return result;
    }
};
相关推荐
1000世界小札2 小时前
《大话数据结构》第9章精读:归并排序与快速排序完整 C++ 实现
数据结构·c++·算法
2601_956121974 小时前
背包基础篇(01、完全、分组、多重、混合)
c++·算法·动态规划
兴通物联科技5 小时前
SMT PCB 微小 DataMatrix 码扫不动问题分析 兴通 XT8601B 600 万像素工业读码器落地实践
大数据·人工智能·单片机·嵌入式硬件·算法·计算机视觉
月华路8 小时前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
我想走路带风8 小时前
LRU和最长前缀和(计算机网络算法)
计算机网络·算法
M78佐菲8 小时前
Linux学习笔记:进程
linux·笔记·学习·算法
徐小夕10 小时前
表格、文档、甘特、大屏、表单一站打通:pxcharts超级表格4.0正式上线!
前端·算法·github
Xin77010 小时前
LeetCode 23.合并 K 个升序链表(分治递归)
leetcode
TechLee11 小时前
跨语言加解密总对不上?这个纯 Go 神库让 AES/RSA 与 PHP、Java 100% 互通
java·后端·算法