【代码随想录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;
    }
};
相关推荐
可编程芯片开发29 分钟前
基于模糊PID控制的六步逆变器供电无刷直流电机调速simulink仿真
算法
imperialeast1 小时前
WinAXP音乐播放器8月4日更新
windows·算法·ui
ZhouDevin1 小时前
算法论文/模型微调1——CNN架构做lora微调训练
人工智能·深度学习·算法·架构·cnn
小月土星1 小时前
LeetCode 21. 合并两个有序链表 超详细题解(虚拟头结点 + 逐行代码拆解)
算法
oier_Asad.Chen1 小时前
【OI学习笔记】Floyed-Warshall算法解决传递闭包问题
c++·笔记·学习·算法·图论·最短路·传递闭包
国科安芯1 小时前
卫星星务计算机数据管理中SEU容错机制的技术实现研究——以AS32S601存储器ECC架构为例
网络·单片机·算法·fpga开发·架构·云计算·risc-v
孙启超1 小时前
【AI应用开发】Agent 无限 loop(反复调用同一个工具)如何规避?
人工智能·python·算法·llm·agent·loop·ai应用开发
小月土星2 小时前
LeetCode 142. 环形链表 II 超详细题解(快慢指针原理+逐行代码拆解)
算法
dok122 小时前
Johannes 《Linux内核模块与设备驱动开发:编写Linux驱动程序》 (11)kmalloc 动态内存分配和struct file中的私有数据
linux·驱动开发·算法
hansang_IR2 小时前
【题解】[COCI 2024/2025 #2] 流明 / Blistavost
c++·算法·动态规划·dp