剑指offer-48:最长不含重复字符的子字符串

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

定义函数f(i)表示以第i个字符为结尾的不包含重复字符的子字符串的最大长度。下面以第i个字符之前有没有出现过重复字符分为两种情况讨论。

如果第i个字符之前没有出现过重复字符,即f=f(i-1)+1。在字串“dhabcacfh”
中,显然f(0)=1,计算下标为1的h之前没有出现过h,所以f(1)=f(0)+1=2。最长的不包含重复字符的子字符串为“dh”。

如果第i个字符之前出现过重复字符,就要计算第i个字符和它上次出现在字符串中得位置的距离d。分两种情况:

(1)如果d小于或等于f(i-1),此时第i个字符上次出现在f(i-1)对应的最长子字符串中,因此f(i)=d;

(2)如果d大于f(i-1),此时第i个字符上次出现在f(i-1)对应的最长子字符串之前,f=f(i-1)+1成立依然。以字符串“dhabcacfh”为例,在最后一个字符h之前以f为结尾的最长不包含重复字符的字符串是"acf",即f(7)=3。最后一个字符h在字符串“arabcacfr”中下标为1的位置出现过,即d=7>f(7),说明上一个字符h不在f(7)对应的最长子字符串"acf"中,因此f(8)=f(7)+1=4。即以h为结尾的最长不包含重复字符的字符串是"acfh"。

代码如下:

#include<stdio.h>
#include<stdlib.h>
int longestStrNoRepetition(char *str, int length)
{
	int curLength = 0;
	int maxLength = 0;
	int *position = (int *)malloc(26 * sizeof(int));
	//下标初始化为-1表示i对应的元素还没在str中出现过
	for (int i = 0; i < 26; ++i)
	{
		position[i] = -1;
	}
	for (int i = 0; i < length; i++)
	{
		int preIndex = position[str[i] - 'a'];
		//第i个字符之前没出现过重复字符
		if (preIndex<0 || i - preIndex>curLength)
			++curLength;
		else
		{
			//第i个字符之前出现过重复字符
			if (curLength>maxLength)
				maxLength = curLength;
			curLength = i - preIndex;
		}
		//标记i出现在str字符串中的下标
		position[str[i] - 'a'] = i;
	}
	if (curLength>maxLength)
		maxLength = curLength;
	free(position);
	position = NULL;
	return curLength;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值