找出一个字符串中不含重复字符的最长子字符串
采用动态规划,若已知以第i-1位字符为结尾的最长子字符串长度l[i-1],并知道第i-1位字符上一次出现的位置k,就可以求出以第i个字符为结束的最长子字符串(min(l[i-1]+1,i-k)。
遍历字符串就可以求出最长子串,时间复杂度为O(n),代码如下
#include "stdafx.h"
#include
using namespace std;
#define min(a, b) (((a) < (b)) ? (a) : (b))
void Find(const char* str,int len)
{
if(str == NULL)
{
return;
}
int prev[255];
for(int i=0; i<255; i++)
{
prev[i] = -1;
}
int *maxlen = new int[len];
maxlen[0] = 1;
prev[str[0]] = 0;
for(int i=1; i
{
if(prev[str[i]] == -1)
{
maxlen[i] =maxlen[i-1]+1;
}
if(prev[str[i]] != -1)//occur
{
maxlen[i] = min(maxlen[i-1]+1,i-prev[str[i]]);
}
prev[str[i]] = i;
}
int l = 0;
for(int i=0; i
{
if(l
{
l = maxlen[i];
}
}
for(int i=0; i
{
if(maxlen[i] == l)
{
for(int j = i-l+1; j<=i; j++)
{
cout<
}
cout<
}
}
}
int main(void)
{
const char* arr[] ={"ttdjb", "niceday", "helloworld",NULL};
for(int i = 0; arr[i]; ++i)
{
Find(arr[i],strlen(arr[i]));
}
//Find("abcabc",6);
return 0;
}
计算字符串中不包含重复字符的最大子字符串长度,算法应道尽可能高效。
例:“xabcdaef”中"xabcd"和"bcdaef"都不含重复字符的子字符串,其中"abcda"则是包含重复子字符串的。最大不含重复字符的子字符串"bcdaef"的长度是6,因此返回值:6。
int search(const char* test)
{
int lastPos[256]; //每个字符的上一次访问的元素位置
int maxLen = 0; //最大字符不重复字符子串长度
int curLen = 0; //记录当前字符不重复字符子串的长度
memset(lastPos,-1,sizeof(int) * sizeof(lastPos)); //记每个字符第一次访问的位置为-1
for (int i = 0; i < strlen(test); i++)
{
//如果当前字符位置与上次位置之间的距离 > 当前子字符串内的距离,
//则说明在当前curLen的范围内不存在当前字符的重复,所以curLen+1;
//否则当前curLen = i - lastPos[test[i]],即不重复字符字串长度为当前的字符
//与其上次位置之间的距离
if (i - lastPos[test[i]] > curLen)
{
curLen++;
maxLen = max(curLen,maxLen);
lastPos[test[i]] = i;
}
else
{
curLen = i - lastPos[test[i]];
lastPos[test[i]] = i;
}
}
return maxLen;
}