题目描述:

   最长不重复子串(Longest No Repeat String,LNRS)就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的。

分析:

解法一:动态规划

  动态规划就是用来解决这种最优化问题,关于字符串的很多有趣的问题如最长公共自序列,最长上升子序列等都可以用动态规划来解,这道题我的第一想法也是动态规划。

  动态规划的核心在于寻找最优子结构,对于一个字符,如果他与他前面的最长不重复子串都没有相同的字符,那么他也可以加入这个子串中,构成一个新的子串。即对于字符数组a[],dp[i]表示以a[i]为结尾的最长不重复子串长度,dp[0] = 1,最后取dp中的最大值即可。代码如下:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <string.h>
 4 
 5 using namespace std;
 6 char in[10001];
 7 
 8 int dp[10001];
 9 
10 int LNRS_dp(char *in)
11 {
12     int i, j;
13     int len = strlen(in);
14     int last = 0;     // 上一次最长子串的起始位置
15     int maxlen,maxindex;
16     maxlen = maxindex = 0;
17  
18     dp[0] = 1;
19     for(i = 1; i < len; ++i)
20     {
21         for(j = i-1; j >= last; --j) // 遍历到上一次最长子串起始位置
22         {
23             if(in[j] == in[i])
24             {
25                 dp[i] = i - j;
26                 last = j+1; // 更新last_start
27                 break;
28             }else if(j == last) // 无重复
29             {
30                 dp[i] = dp[i-1] + 1;//长度+1 
31             }
32         }
33         if(dp[i] > maxlen)
34         {
35             maxlen = dp[i];
36         }
37     }
38     return maxlen;
39 }
40 
41 int main()
42 {
43      freopen("1530.in","r",stdin);
44      freopen("1530.out","w",stdout);
45      
46      while(scanf("%s",in)!=EOF)
47      {
48           printf("%d\n",LNRS_dp(in));
49      }
50      return 0;
51 }
View Code

相关文章: