当前位置: 首页 > news >正文

划分字母区间

划分字母区间

1.1 题目描述

  给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。例如,字符串 “ababcc” 能够被分为 [“abab”, “cc”],但类似 [“aba”, “bcc”] 或 [“ab”, “ab”, “cc”] 的划分是非法的。
  注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。返回一个表示每个字符串片段的长度的列表。

1.2 示例

1.2.1 示例1

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

1.2.2 示例2

输入:s = “eccbbbbdec”
输出:[10]

1.3 提示

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

1.4 思路:

  首先,通过对题目的分析,可以将题目理解为需要把字符串s进行若干份分割,但是划分的每一个字符串里面出现的字符只能属于该字符串,不能出现在划分的其他字符串里面,当然最简单的划分就是划分为一个字符串,但是不满足划分的字符串数尽可能多的条件。
  因此可以通过遍历字符串,判断每个字符在s中开始出现的位置和最后出现的位置,如果该字符只出现过一次,则它的开始位置和结束位置相同,最后就会得到一个长度为n(n表示不同字符的个数)的2维数组。而问题的计算可以转化为对这些区间合并的计算。
  比如字符串s="ababcbacadefegdehijhklij",每个字符的区间可以划分为a=[0,8],b=[1,5],c=[4,7],d=[9,14],e=[10,15],f=[11,11],g=[13,13],h=[16,19],i=[17,22],j=[18,23],k=[20,20],l=[21,21]。得到这个区间之后就可以开始进行合并,a的区间是[0,8],因为b在a的区间之内,c也在a的区间内,d不在a的区间内,所以第一个区间就是[0,8],第二个区间从d=[9,14]开始,e的右区间在d里面,左区间在d区间之外,因此d和e的合并区间是[9,15],以此类推,f和g也在第二个区间内,h不在第二个区间内,于是得到第二个区间[9,15],同理可以得到第三个区间[16,23]。最后三个区间分别是[0,8][9,15][16,23],字符长度为9,7,8。

1.5 代码

#include<bits/stdc++.h>
using namespace std;
vector<int> partitionLabels(string s) { 
    map<char,vector<int>> my_map;
    vector<int> results;
    for(int i=0;i<s.length();i++){
        vector<int> indexs = my_map[s[i]];
        if(indexs.size()==0){
            indexs.push_back(i);
            indexs.push_back(i);
        }else{
            indexs[1] = i;
        }
        my_map[s[i]] = indexs;
    }
    int start=0;
    int end=0;
    for(auto m=my_map.begin();m!=my_map.end();m++){
    	cout<<m->first<<" "<<m->second[0]<<"-"<<m->second[1]<<endl;
	}
	for(int i=0;i<s.size();i++){
		vector<int> indexs = my_map[s[i]];
		if(indexs[0]>=start&&indexs[0]<=end){
    		if(end<indexs[1]){
    			end = indexs[1];
			}
		}else if(indexs[0]>start){
		  	results.push_back(end-start+1);
		    start = indexs[0];
		    end = indexs[1];
		}else{
			cout<<"err"<<endl;
		}
	}
	results.push_back(end-start+1);
	return results;
}
int main(){
	string s = "ababcbacadefegdehijhklij";
	vector<int> results = partitionLabels(s);
	cout<<endl<<"结果:"<<endl;
	for(int i=0;i<results.size();i++){
		cout<<results[i]<<" ";
	}
	return 0;
}

运行结果
在这里插入图片描述

  当然解决该类问题还有很多方法,该方法只是比较简单和方便理解的一种,如果为了提高性能,大家还可以进行另外的分析。

相关文章:

  • 【Qt】常用控件(一)
  • 【练习】【二分】力扣热题100 153. 寻找旋转排序数组中的最小值
  • C++ Qt建立一个HTTP服务器
  • 鸿蒙开发:V2版本装饰器之@Monitor装饰器
  • 阐解WiFi信号强度
  • Linux centOS7 bash编程小技巧
  • Vue3中的setup
  • Linux应用之构建命令行解释器(bash进程)
  • vue3之echarts柱状图-圆锥加自动轮播
  • 使用Termux将安卓手机变成随身AI服务器(page assist连接)
  • Pyrhon函数-装饰器第一部分250219
  • C程序设计(第5版)——谭浩强(2)
  • 构建简单RAG代码实现
  • java常见面试场景题
  • nodejs各版本下载地址 —— 筑梦之路
  • 【Java】泛型与集合篇 —— 泛型
  • virt-io 如何运行在 kvm windows 虚拟机上
  • rust学习三、基本类型
  • Spring框架基本使用(Maven详解)
  • 【二分搜索 C/C++】洛谷 P1873 EKO / 砍树
  • 始祖鸟母公司一季度净利大增超25倍:中国营收增超四成,从容应对关税影响
  • 上海古镇“长效”发展需要提高社会资本参与
  • 四川省政府党组成员、副省长、省公安厅厅长叶寒冰接受审查调查
  • 时隔5个月,辽沈银行行长再调整
  • 深圳南山法院回应“执行款未到账”:张核子公司申请的执行异议成立
  • 国家消防救援局应急通信和科技司负责人张昊接受审查调查