找出一个字符串中不含重复字符的最长子字符串

找出一个字符串中不含重复字符的最长子字符串

采用动态规划,若已知以第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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值