#1039:字符消除

本文探讨了一种消除连续重复字符的算法,通过使用栈结构改进了原有算法的时间复杂度,从O(N^2)降低到O(N),并讨论了算法在实际应用中的局限性和可能的进一步优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提取主要需求:即消除连续出现的两个以上的字符,直到新生成的字符串不满足条件。

初步分析

设置一个flag标志前一次循环是否有消除操作,如果有,则开始下一次的循环。可该如何判断是否可以消除字符呢?

  • 此时追加一个for循环,将字符串的起始位置设为标记点,检查其后的字符是否与标记点字符相同;

  • 若相同,则将其位置置为终止位置;若不同,则删除首位置元素(放入最终字符串变量result中,该字符串记录算法终止时不可消除的字符);

伪代码如下:

flag = true; result = "";
while flag 
	j = 2;
	len = input.length;
	for i = 1 to len
		if 下一个字符与首位置字符相同 then : j = j+1;
		else if j > 1 then : 删除j之前的元素; flag = true;
							 截取j之后的子串,替换input;
		else 将首元素加入result,用作下一轮的while消除;
	input = result;

插入操作则可使用for循环,遍历所有课插入位置,得到最高分。

再度思考

基于初步的分析,不难看出插入字符操作并未要求得到插入的具体位置,那么这是否意味着我们可以先进行消除得到一个未插入状态的最终字串,然后再进行插入得到最终字串呢?

好像是可以的?但实际并不对,思考有这种情况:“BCBB”,先进行消除得到未插入字符状态的最终字串,即**“BC”,然后插入再消除,发现无论如何插入,最终字串都至少含有一个字符。显然,如果是先进行插入操作得到“BCCBB”,再进行消除得到的最终字串为空串**!

对比之下可知,这一步是不可实现的。

那么,消除函数应该是可以更进一步的吧?在初步分析中,假设while循环执行N次(但**实际上是不可能执行N次的***),for循环N次,我们只记if中的判断条件为有效的基础运算,即3次(最大),则有3NN = 3N^2 = O(N^2) 的最坏时间复杂度,这么看来,是有提升空间的。

基于以上分析,这一次的消除函数选用来进行:

  1. 若上一次有发生消除操作,则进入本次的消除检查。
  2. 从字符串其实位置开始,主次入栈,每次如栈前检查栈顶元素 == 准备入栈元素。
  3. 若不等,栈空间>2则舍弃栈中所有元素,并压入下一元素;否则弹出栈顶元素,计入result字串中。

算法结束时返回最终串与初始串的长度差。

粗略计算,while循环N次(实际并不是),内部的有效基本运算记为m,则算法时间复杂度为 m*N = O(N) 线性阶。

不完整的伪代码如下(这里其实有一个小问题使得算法没能达到线性阶,在哪里呢?):

flag = true; i = 0; result = "";
while flag 
	s.push(input[i]);
	while input[i++] = s.top()
		s.push(input[i];
	if s.size() > 1 then : s.clear(); flag = true;
	else result += s.top(); s.pop();
	input = result; result = "";
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值