贪心算法 | 763.划分字母区间

·题目描述

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

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

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

示例 1:

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

示例 2:

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

·解题思路

很质朴的想法是,遍历一圈字符串s, 把每个字母出现的起始位置用数组记录下来。再套用之前leetcode 452 用最少数量的箭引爆气球  和 leetcode 435 无重复区间的 思路, 将数组进行规划;

规划分为三步:1.最开始的位置进行排序;2.当后一个数组的开始位置小于前一个数组的结束位置的时候,说明两个数组有重叠,更新数组区间;3.当后一个数组的开始位置大于前一个数组的结束位置的时候,说明两个数组没有重叠区间,需要计算前一个数组的字符串长度

·解题细节:

1.每一个字母都可能出现,因此创建26*2的二维数组,计算每一个出现的字母的开始和结束位置。同时,如何判断该数字是开始坐标还是结束坐标------创建flag数组来标记,若是flag = 0 ,表示之前没有出现过,该坐标为起始坐标,反之则为结束坐标。结束坐标需要不断更新;

            int[][] num = new int[26][2];int[] flag = new int[26];for(int i = 0; i < s.length(); i++){int temp  = s.charAt(i) - 'a';if(flag[temp] == 0){num[temp][0] = i;flag[temp] = 1;}else{ num[temp][1] = Math.max(num[temp][1], i);}}

2.对记录的字母坐标按照第一个元素进行排序

Arrays.sort(num, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return Integer.compare(o1[0], o2[0]);}});#打印结果for(int i = 0; i < num.length; i++){System.out.println(num[i][0] + " " + num[i][1]);}

3.对坐标数组进行处理,遍历num数组,利用栈来辅助更新区间。当当前数组的开始位置小于栈顶数组的结束位置的时候,说明两个数组有重叠,更新数组区间;反之说明两个数组没有重叠区间,需要计算前一个数组的字符串长度

        Stack<int[]> stack = new Stack<int[]>();for(int i = 0;i < num.length;i++){#当栈为空的时候,先压入if(stack.isEmpty()) stack.push(num[i]);else{int[] point = stack.peek();if(num[i][0] < point[1]){int newend = Math.max(point[1], num[i][1]);int[] newpoint = new int[] {point[0],newend};stack.pop();stack.push(newpoint);}else{int len = stack.peek()[1] - stack.peek()[0] + 1;res.add(len);stack.pop();stack.push(num[i]);}}}

4.有可能最后一个子字符串不能满足for循环的收割条件,也就是说栈不为空,这是还需要处理

        while(!stack.isEmpty()){int[] point = stack.pop();if(point[1] == 0) {res.add(1);count += 1;}else{int len = point[1] - point[0] + 1;res.add(len);}}

5.处理空数组:

由于给出的字符不一定包含26个字母,也就是说num中有很多空数组参与了排序,这时候只需要在遍历的时候,当数组两个元素都是0的时候,continue即可

if(num[i][0] == 0 && num[i][1] == 0){continue;}

6.处理单个元素

字符串中可能存在单个元素,分为两种情况:头单个【0,0】和其他【x(x!= 0) , 0】

处理头单个的时候,只需要增加一个count技术,当所有子串的长度小于给定字符串的长度时,说明有头单个元素漏加,只需要在列表结构头部增加 1 ,即可

处理其他单个元素的时候,只需要在遍历num时,当数组第一个元素不为0,而第二元素为0 的时候,将第二个元素变为第一个元素相同值即可

            if(num[i][0] == 0 && num[i][1] == 0){continue;}if(num[i][0] != 0 &&  num[i][1] == 0){num[i][1] = num[i][0];}

·java代码

import java.util.*;class Solution {public List<Integer> partitionLabels(String s) {int[][] num = new int[26][2];int[] flag = new int[26];int count = 0;for(int i = 0; i < s.length(); i++){int temp  = s.charAt(i) - 'a';if(flag[temp] == 0){num[temp][0] = i;flag[temp] = 1;}else{ num[temp][1] = Math.max(num[temp][1], i);}}Arrays.sort(num, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return Integer.compare(o1[0], o2[0]);}});for(int i = 0; i < num.length; i++){System.out.println(num[i][0] + " " + num[i][1]);}List<Integer> res = new ArrayList<Integer>();Stack<int[]> stack = new Stack<int[]>();for(int i = 0;i < num.length;i++){if(num[i][0] == 0 && num[i][1] == 0){continue;}if(num[i][0] != 0 &&  num[i][1] == 0){num[i][1] = num[i][0];}if(stack.isEmpty()) stack.push(num[i]);else{int[] point = stack.peek();if(num[i][0] < point[1]){int newend = Math.max(point[1], num[i][1]);int[] newpoint = new int[] {point[0],newend};stack.pop();stack.push(newpoint);}else{int len = stack.peek()[1] - stack.peek()[0] + 1;res.add(len);count += len;stack.pop();stack.push(num[i]);}}}while(!stack.isEmpty()){int[] point = stack.pop();if(point[1] == 0) {res.add(1);count += 1;}else{int len = point[1] - point[0] + 1;res.add(len);count += len;}}if(count < s.length()) res.add(0,1);return res;}
}public class Main {public static void main(String[] args) {Solution solution = new Solution();System.out.println(solution.partitionLabels("vhaagbqkaq"));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/875471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决zabbix-server7 中文乱码问题

系统使用centos9 安装中文支持 yum install -y fontconfig langpacks-zh_CN.noarch 检查是否已有中文字体&#xff1a; fc-list :langzh 看到 直接使用GOOGLE的字体 ln -fs /usr/share/fonts/google-noto-cjk/NotoSansCJK-DemiLight.ttc /etc/alternatives/zabbix-web-fo…

bool数组的理解和应用[C++]

文章目录 bool数组的用法bool数组的定义声明bool数组的初始化访问和修改数组元素遍历数组 运用bool数组简单代码 在今天做题中发现了bool类不仅能用于函数类型还能用于数组类型&#xff0c;好奇查了查发现bool还有很多用处&#xff1a;基本变量&#xff0c;在枚举类型中会用到&…

【C语言】结构体详解 -《探索C语言的 “小宇宙” 》

目录 C语言结构体&#xff08;struct&#xff09;详解结构体概览表1. 结构体的基本概念1.1 结构体定义1.2 结构体变量声明 2. 结构体成员的访问2.1 使用点运算符&#xff08;.&#xff09;访问成员输出 2.2 使用箭头运算符&#xff08;->&#xff09;访问成员输出 3. 结构体…

【CSS】1 像素问题

CSS 中的 1 像素问题指的是在⾼分辨率屏幕上显示的 1 像素边框或者细线在实际显示时会⽐ 1 个物理像素更宽或更粗&#xff0c;从⽽导致边框或者细线看上去⽐预期的更粗或者更宽。 造成这个问题的原因是由于⾼分辨率屏幕的像素密度⽐传统的屏幕要⾼&#xff0c;所以在屏幕上显示…

一个C++模板工厂的编译问题的解决。针对第三方库的构造函数以及追加了的对象构造函数。牵扯到重载、特化等

一窥模板的替换和匹配方式&#xff1a;偏特化的参数比泛化版本的还要多&#xff1a;判断是不是std::pair&#xff1c;,&#xff1e;。_stdpair模板参数太多-CSDN博客 简介 在一个项目里&#xff0c;调用了第三封的库&#xff0c;这个库里面有个类用的很多&#xff0c;而且其构…

边界网关IPSEC VPN实验

拓扑&#xff1a; 实验要求&#xff1a;通过IPSEC VPN能够使PC2通过网络访问PC3 将整个路线分为三段 IPSEC配置在FW1和FW2上&#xff0c;在FW1与FW2之间建立隧道&#xff0c;能够传递IKE&#xff08;UDP500&#xff09;和ESP数据包&#xff0c;然后在FW1与PC2之间能够流通数据…

GitHub 详解教程

1. 引言 GitHub 是一个用于版本控制和协作的代码托管平台&#xff0c;基于 Git 构建。它提供了强大的功能&#xff0c;使开发者可以轻松管理代码、追踪问题、进行代码审查和协作开发。 2. Git 与 GitHub 的区别 Git 是一个分布式版本控制系统&#xff0c;用于跟踪文件的更改…

学术研讨 | 基于区块链的隐私计算与数据可信流通研讨会顺利召开

近日&#xff0c;由国家区块链技术创新中心组织的“基于区块链的隐私计算与数据可信流通研讨会”顺利召开&#xff0c;会议邀请了来自全国高校和科研院所的相关领域专家&#xff0c;围绕基于区块链与隐私计算技术的应用需求、研究现状、发展趋势、重点研究方向与研究进展等内容…

Go并发GMP调度模型

如何知道一个对象是分配在栈上还是堆上&#xff1f; Go和C不同&#xff0c;Go的逃逸分析是在编译器完成的&#xff1b;go局部变量会进行逃逸分析。如果变量离开作用域后没有被引用&#xff0c;则优先分配到栈上&#xff0c;否则分配到堆上。那么如何判断是否发生了逃逸呢&#…

数据结构之《队列》

在数据结构之《栈》章节中学习了线性表中除了顺序表和链表外的另一种结构——栈&#xff0c;在本篇中我们将继续学习另一种线性表的结构——队列&#xff0c;在通过本篇的学习后&#xff0c;你将会对栈的结构有充足的了解&#xff0c;在了解完结构后我们还将进行栈的实现。一起…

vue3-02声明响应式状态ref()

一、使用 组合式 API 中&#xff0c;推荐使用 ref() 函数来声明响应式状态&#xff0c;例如 import { ref } from vue const count ref(0)注意点1&#xff1a;若想获取ref定义的参数&#xff0c;必须获取参数的value值&#xff0c; 比如&#xff1a; console.log(count, co…

2024海外电商数据分析之南美篇

南美洲&#xff0c;一片广袤而充满活力的大陆&#xff0c;以其独特的地理位置和丰富的自然资源&#xff0c;孕育了15个国家和4.3亿人口。与北美洲的三国&#xff08;美国、加拿大和墨西哥&#xff09;及中美洲的七国相比&#xff0c;南美洲以其年轻的人口结构和巨大的市场潜力&…

【LLM】-08-搭建问答系统-语言模型,提问范式与 Token

目录 1、语言模型 1.1、训练过程&#xff1a; 1..2、大型语言模型分类&#xff1a; 1.3、指令微调模型训练过程&#xff1a; 2、Tokens 3、Helper function辅助函数 (提问范式) 4、计算token数量 1、语言模型 大语言模型&#xff08;LLM&#xff09;是通过预测下一个词…

一款允许使用Docker部署本地托管的、基于 Web 的 PDF 操作工具

大家好&#xff0c;今天给大家分享的是一个基于Spring Boot开发的开源项目&#xff0c;旨在提供一个功能强大的基于Docker的本地托管PDF操作工具Stirling PDF。 项目介绍 Stirling-PDF是一个全面的PDF工具箱&#xff0c;适用于个人和企业用户&#xff0c;尤其对于那些重视数据…

js 优雅的实现模板方法设计模式

在JavaScript中&#xff0c;优雅地实现模板方法设计模式通常意味着我们要遵循一些最佳实践&#xff0c;如清晰地定义算法的骨架&#xff08;模板方法&#xff09;&#xff0c;并确保子类能够灵活地扩展或修改这些算法中的特定步骤。由于JavaScript是一种动态语言&#xff0c;我…

CasaOS设备使用Docker安装SyncThing文件同步神器并实现远程管理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

巨量数据表分页问题

1 背景 分页性能问题,之前遇到过这类问题,拿出来再讨论下 2 分析 分页性能问题,特别是在数据量大的情况下,是一个常见的问题。通常,当我们使用类似 LIMIT 和 OFFSET 的SQL语句进行分页时,性能问题尤其明显。这是因为随着 OFFSET 的增加,数据库需要跳过更多的行才能获…

C++树形结构(1 基础)

目录 一.基础&#xff1a; 1.概念&#xff1a; 2.定义&#xff1a; Ⅰ.树的相关基础术语&#xff1a; Ⅱ.树的层次&#xff1a; 3.树的性质&#xff1a; 二.存储思路&#xff1a; 1.结构体存储&#xff1a; 2.数组存储&#xff1a; 三.树的遍历模板&#xff1a; 四.信…

用 python scipy 库模拟拥塞控制模型

接着昨天的继续说&#xff0c;参见 inflight 守恒建模。 欧拉数值解看起来不够优雅&#xff0c;所以我打算找个别的方式试一下&#xff0c;顺便学一下 python&#xff0c;我不会编程&#xff0c;但也不是一点也不会&#xff0c;我稍微会一点&#xff0c;所以想进一步学习一点。…

记录unraid docker更新的域名

背景&#xff1a;级联 一、安装内容 unraid更新docker&#xff0c;之前一直失败&#xff0c;修改网络后可以进行安装。 二、查看域名 查看域名&#xff0c;发现是走github的&#xff0c;怪不得有一些docker无法正常更新 三、解决方法 更改代理&#xff0c;这里为unraid的…