希望的每日一题(字符串分割)

问题描述:

就是一个字符串分割问题,尽可能分到最小并且一种字符只能出现在一个子字符串
例如:abac —>> aba 和 c
输出:3 1 (每个子串的长度)
注意:要求尽可能短的分割
例如:abacde 不可分割为aba cde 要分割为aba c d e

思路:

  • 要求一种字符只能在一起那么两个相同字母以及中间夹住的是必然在一起的。例如:abacab这个串中,aba是在一起的,aca是在一起的。
  • 那么一种字母最左边的和最右边的以及夹在中的时必然在一个子串的。例如:abacab这个串中,abaca是必然在一起的。
  • 那么每一种字母都这样想的话,我们可以看abaca这个子串中是有另外两种字母b和c的那么其他所有的b和c都要和这个子串在一起的。

解决:

#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
int max(int a, int b);
void Resolve(string S, vector<int>& ret);
int main() {
	string S;
	vector<int> ret;
	cin >> S;
	Resolve(S,ret);
	for (int i = 0; i <(int) ret.size(); i++)
		cout << ret[i];
}

void Resolve(string S,vector<int>&ret) {
	int Alpha[26];
	memset(Alpha, 0, sizeof(Alpha));
	//记录每个字符的最右边的下标
	for (int i = 0; i <(int) S.length(); i++) {
		Alpha[S[i] - 'a'] = i;
	}
	//设l和r两个指针
	int l = 0;
	int r = Alpha[S[l]-'a' ];
	while (l < (int) S.length()) {
		int l0 = l;
		while (l < r) {
			++l;
			r = max(r, Alpha[S[l]-'a']);
		}
		//将每个子串的长度写入容器
		ret.push_back(l - l0 + 1);
		l++;
	}
}

int max(int a, int b) {
	if (a > b)return a;
	else return b;
}

解释:

  • 我感觉这种方法很巧妙,我的想法就是开始将l和r指针分别在一种字母的最左边一个和最右边一个。
int l = 0;
	int r = Alpha[S[l]-'a' ];
  • 然后对中间的进行尝试的扩展边界。如果能扩展边界就扩展,不能扩展就保留原来的边界
r = max(r, Alpha[S[l]-'a']);
  • 直到 l == r 时扩展结束
  • 注意一轮扩展结束之后需要将l指针指向第二个子串首字母的位置
  • 直到 l == 到了字符串最后一位结束
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值