首页 > 其他分享 >力扣-763. 划分字母区间

力扣-763. 划分字母区间

时间:2024-06-20 16:56:35浏览次数:28  
标签:letters int 763 字母 力扣 startTime 字符串 endTime

题目地址(763. 划分字母区间 - 力扣(LeetCode))

https://leetcode.cn/problems/partition-labels/

题目描述

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s

返回一个表示每个字符串片段的长度的列表。

 

示例 1:
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。 

示例 2:

输入:s = "eccbbbbdec"
输出:[10]

 

提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成

2.题解

2.1 贪心算法

思路

这里一个组内第一个元素,我们是必须找到并且达到其最后出现位置,否则无法满足同一字母最多出现在一个片段中
在其中我们可能会遇到其他的字母,这些字母也有其最后出现位置,而且我们贪心策略必须满足:我们最后该组的停止位置必须涵盖所有遇到的字母最后出现位置
也就是说,我们贪心不断更新该组的结束位置为这些字母中最晚的一个出现位置即可

代码1

  • 语言支持:C++

C++ Code:


class Solution {
public:
    vector<int> partitionLabels(string s) {
        vector<int> letters(26), ans;
        // 初始化各字符最后出现位置
        for(int i = 0; i < s.length(); i++){
            letters[s[i] - 'a'] = i;
        }

        //设置初始值
        int endTime = -1, n = s.length();
        // 当endTime == n - 1时, 代表已经来到末尾
        while(endTime < n - 1){ // 这里 while(endTime < s.length()会不满足为 0,类型不同) 
            // 新的一组从老的最后一组向后推一个
            int cnt = 0;
            int startTime = endTime + 1; // 向后推一个
            endTime = letters[s[endTime + 1] - 'a']; // 找到新组第一个字母最后出现的位置
            // 一个新的组别
            while(startTime <= endTime){
                cnt++; // 记录次数
                endTime = max(endTime, letters[s[startTime]- 'a'] ); // 更新一组内最后出现的字母位置
                startTime++; // 向后推进
            }
            ans.push_back(cnt);
        }
        return ans;
    }
};

代码2-改进

我代码一种的逻辑有一些复杂,两个while循环嵌套,初始值的设置-1,endTime的两次更新,这些层层相嵌,导致逻辑很容易混乱
所以根据力扣题解代码进行了改进:
这里其实只需要一个for循环即可,然后实时更新最新的endTime, 计算cnt也不需要每次cnt++, 只需要知道起始位置startTime和endTime即可
再下一组的时候,只需要startTime = endTime + 1;就相当于分组了,不需要单独对于二者都进行重新设置了, i++作为遍历迭代器而不是startTime了!!!

class Solution {
public:
    vector<int> partitionLabels(string s) {
        vector<int> letters(26), ans;
        // 初始化各字符最后出现位置
        for(int i = 0; i < s.length(); i++){
            letters[s[i] - 'a'] = i;
        }

        int startTime = 0, endTime = 0;
        for(int i = 0; i < s.length(); i++){
            endTime = max(endTime, letters[s[i] - 'a']);
            if(i == endTime){
                int cnt = endTime - startTime + 1;
                ans.push_back(cnt);
                startTime = endTime + 1;;
            }
        }
        return ans;
    }
};

复杂度分析

·时间复杂度:\(O(n)\),其中\(n\)是字符串的长度。需要遍历字符串两次,第一次遍历时记录每个字母最后一次出现的下标位置,第二次遍历时进行字符串的划分。

空间复杂度\(:O(|\Sigma|)\),其中 Σ是字符串中的字符集。这道题中,
字符串只包含小写字母,因此\(|\Sigma|=26\) 。

标签:letters,int,763,字母,力扣,startTime,字符串,endTime
From: https://www.cnblogs.com/trmbh12/p/18258923

相关文章

  • 力扣-452. 用最少数量的箭引爆气球
    1.题目介绍题目地址(452.用最少数量的箭引爆气球-力扣(LeetCode))https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/题目描述有一些球形气球贴在一堵用XY平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i]=[xstart,xend]......
  • 力扣每日一题 6/19 排序+动态规划
    博客主页:誓则盟约系列专栏:IT竞赛专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞......
  • 力扣每日一题 6/17 枚举+双指针
    博客主页:誓则盟约系列专栏:IT竞赛专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞......
  • 力扣-435.无重叠区间
    1.题目介绍题目地址(435.无重叠区间-力扣(LeetCode))https://leetcode.cn/problems/non-overlapping-intervals/题目描述给定一个区间的集合 intervals ,其中intervals[i]=[starti,endi] 。返回需要移除区间的最小数量,使剩余区间互不重叠 。 示例1:输入:interv......
  • 力扣2713 2024.6.19
    原题网址:此处为链接个人难度评价:1700分析:DP顺序很重要,从大数递推到小数保证了不会每次都是最优子结构而不会有后效性。开了个map来方便二分大于当前数的最小数,状态转移方程显然,记h[x]与l[y]表示第x行小于当前值的最优和第y列小于当前值的最优:dp[x][y]=max(f[x],l[y])注意......
  • 汇编语言程序设计 - 将当前目录下文件 FIE10.TXT 的所有小写字母改为大写字母,然后拷贝
    80x86汇编题目题目描述:编写一个程序,将当前目录下文件FIE10.TXT 的所有小写字母改为大写字母,然后拷贝到当前目录文件FILE20.TXT。思路:1,分别打开两个文件,保存文件句柄2,读取FILE10文件的一个字节到BUF内存中。3,判断是否为小写。非小写字母直接写入到FILE20文件中,小写字母......
  • N皇后-力扣
    按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n皇后问题研究的是如何将n个皇后放置在n×n的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数n,返回所有不同的n皇后问题的解决方案。每一种解法包含一个不同的n皇后问题的......
  • 编写函数fun,该函数的功能是:从字符中删除指定的字符,同一字母的大、小写按不同字符处理
    编写函数fun,该函数的功能是:从字符中删除指定的字符,同一字母的大、小写按不同字符处理。#include<stdio.h>#include<string.h>voidfun(char*str,charch){intlen=strlen(str);inti,j;for(i=0;i<len;i++){if(str[i]==ch||(......
  • (算法)找到字符串中所有字母异位词——<滑动窗⼝+哈希表>
    1.题⽬链接:438.找到字符串中所有字⺟异位词2.题⽬描述:3.解法(滑动窗⼝+哈希表): 算法思路:◦因为字符串p的异位词的⻓度⼀定与字符串p的⻓度相同,所以我们可以在字符串s中构造⼀个⻓度为与字符串p的⻓度相同的滑动窗⼝,并在滑动中维护窗⼝中每种字⺟的数量; ◦当窗......
  • DAY4-力扣刷题
    1.四数之和18.四数之和-力扣(LeetCode)给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a],nums[b],nums[c],nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):0<=a,b,c,d <na......