c 求字符串内无重复字符的最长子串

来源:互联网 发布:apche怎么使用php 编辑:程序博客网 时间:2024/06/08 18:30
  • 题目描述
    这里写图片描述

  • 分析
    根据题意,最直接暴力的一种方法就是把所有子串都遍历一遍,选出没有重复字符且最长的子串即为结果。注意,本题只需要输出最长子串的长度即可,无需内容。

  • 初版代码

int lengthOfLongestSubstring(char* s) {    int len=strlen(s);    int count=0;    bool isOk=true;    char *tempS;    tempS=(char *)malloc(len);    int longLastIndex=0;  //用来输出最长子串的,但本题中无需用到它    int longLenth=0;    for(int i=0;i<len;){        isOk=true;        for(int j=0;j<count;j++){            if(tempS[j]==s[i]){                isOk=false;                break;            }        }        if(isOk){            tempS[count++]=s[i++];            if(i==len&&longLenth<count){                longLastIndex=i;                longLenth=count;            }        }        else{            if(longLenth<count){                longLastIndex=i;                longLenth=count;            }            i=i-count+1;            count=0;        }    }        return longLenth;}
  • 改进优化
    上述代码的实现就如分析里所说,遍历了所有子串来找结果。事实上,做了很多重复性的工作,比如说字符串“abcabcbb”,当第四位‘a’字符不符合时,又从第2位(i-count+1)字符‘b’开始找,但其实我们在上一轮的时候,就已经比较过‘b’和‘c’了。针对此,我们可以得到更高效的代码,如下:
int lengthOfLongestSubstring(char* s) {    int len=strlen(s);    int count=0;    int start=0;   //记录新子串的起始位置    bool isOk=true;    //char *tempS;    //tempS=(char *)malloc(len);     无需额外的数组来存储    int longLastIndex=0;    int longLenth=0;    for(int i=0;i<len;i++){        isOk=true;        for(int j=0;j<count;j++){            if(s[j+start]==s[i]){     //改动处                isOk=false;                start=j+start+1;             //改动处                break;            }        }        if(isOk){            count++;            if(i==len-1&&longLenth<count){                longLenth=count;            }        }        else{            if(longLenth<count){                longLenth=count;            }            count=i-start+1;   //改动处        }    }    return longLenth;}

该优化的核心思想是用一个start变量记录下发生不满足条件(即子符相同的)位置,那么从start位置到达当前i变量所在的位置之间的子符,便是上一轮匹配中,满足条件的子符,无需再回溯,直接记下其个数再接着匹配就好。

0 0