读书人

求字符串中最长无反复字符的子串

发布时间: 2012-10-16 09:57:37 作者: rapoo

求字符串中最长无重复字符的子串

题目:求一个字符串中最长的没有重复字符的子串。

方法一:穷举法,使用2重外循环遍历所有的区间,用2重内循环检验子串是否符合“无重复字符”这一要求。其中外层循环i、j 遍历所有的下标,m、n是内层循环,检查区间[i,j]是否符合要求。空间复杂度是O(1),时间复杂度O(N^4)。


表中,字符串有3个‘a’,有2个‘b’,其余为单一字符。next[]记录了下一个与之重复的字符的位置,如str[0]=str[8]=str[12]=‘a’,这时next[0]=8,next[8]=12,next[12]=13,其余同理。值得注意的是,对于没有重复字符的,next[]存储字符结束符‘\0’的下标,即13。
这里,first[i]表示i之后,第一次出现重复字符的那个位置。例如,str[0]之后,第一次出现的重复字符是str[5]=‘b’,当然,从str[1],str[2]开始也是一样。而从str[3]开始,要到str[12]才出现重复字符‘a’。可以证明,从str[i]起的最长符合要求的长度为first[i]-i,区间为[i,first[i]-1]由此得解。上述最长串是当i=3时,first[i]-i=12-3=9。结果串为debpqawuv。

//得到字符串最长的无重复的前缀长度int longestlen(char * p){    int hash[256];    int len = 0;    memset(hash,0,sizeof(hash));    while (*p && !hash[*p])    {        hash[*p] = 1;        ++ len;        ++ p;    }    return len;}//使用后缀数组解法int max_unique_substring4(char * str){    int maxlen = -1;    int begin = 0;    char *a[99999];    int n = 0;    while(*str != '\0')    {        a[n++] = str++;    }    for (int i=0; i<n; i++)    {        int temlen = longestlen(a[i]);        if (temlen > maxlen)        {            maxlen = temlen;            begin = i;        }    }    printf("%.*s\n", maxlen, a[begin]);    return maxlen;}


读书人网 >编程

热点推荐