剑指offer 48 最长无重复字符的子字符串

给定一个字符串,请找出其中无重复字符的最长子字符串。

样例

例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 3

对于,"bbbbb",其无重复字符的最长子字符串为"b",长度为1

挑战

O(n) 时间

分析:
利用动态规划

首先定义函数f(i)表示以第i个字符为结尾的不包含重复字符的子字符串的最长长度。

当从左至右扫描字符串中的每个字符时,我们利用f(i-1)计算f(i),两者关系如下:

如果第i个字符之前没有出现过(需要定义一个函数,记录每个字符上次出现在字符串中位置的下标),则f(i)=f(i-1)+1.

如果第i个字符出现过,分为两种情况:先计算第i个字符和它上次出现在字符串中的位置的距离,记为d

  1. d<=f(i-1),则f(i)=d,也证明这个重复字符之间没有其他重复字符了
  2. d>f(i-1),则f(i)=f(i-1)+1,即上一个重复字符不在f(i-1)对应的最长不重复子字符串之内,不会影响到f(i-1)

代码:

int result(const string&str)
{
  int curlength=0;
  int maxlength=0;
  
  int*position=new int[26];//假设总共有26种字符
  for(int i=0;i<26;i++)
  position[i]=-1;//等于-1时证明此字符还未出现过,出现过的字符都被更新了
  //其中i用来代表不同的字符,因为abc...的asii码值大于26,所以我们利用str[i]-'a'来代表str[i]字符
  for(int i=0;i<str.size();i++)
 {
   int index=position[str[i]-'a'];
   if(index<0||i-index>curlength)
    ++curlength;
   else
   {  
     if(curlength>maxlength)
      maxlength=curlength;
      curlength=i-index;
   }
   position[str[i]-'a']=i;//更新字符出现的位置
   if(curlength>maxlength)
      maxlength=curlength;
   delete[] position;
  return maxlength;
}

猜你喜欢

转载自blog.csdn.net/weixin_41413441/article/details/81541175
今日推荐