题目意思:求一字符串中最长的无重复的字符串


一开始拿到这题,直接暴力解决,用双重循环找无重复的子字符串 
结果可想而知,超时!Time Limit Exceeded!

class Solution { public: int lengthOfLongestSubstring(string s) { int max = 0 ; for(int i = 0 ; i < s.length();++i) { int j = i+1; int count = 1; while(j<s.length()) { int z = j-1; while(s[j] != s[z]&&z>=i) z--;//判断是s[j]不等于s[i~j]任一个字符 if(z+1 == i) count++;//如果不等,则count++ j++; } if(max<count) max = count;//记录最大值 } return max; } };

 

 

O(n^2)的复杂度确实太大了,那么,只能另寻他径了。 
降低复杂度的方式:以空间换时间,这里我们可以用到一个数组来记录字符出现过没有。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int last[256]; //字符的ascII码0~256,记录字符最终出现的位置
        memset(last,-1,sizeof(int)*256);//初始化为-1
        int idx = -1;//用来当前字串开始的位置
        int max = 0;
        for(int i = 0; i < s.length() ; ++i)
        {
            if(last[s[i]]>idx)  //①如果这个字符出现过,则令idx等于上一次出现该字符的位置序号
            {
                idx = last[s[i]];  
            } 

            if(i -idx > max){  ②//记录最大的无重复字串
                max = i-idx;
            }

            last[s[i]] = i;③更新last数组
        }
        return max;
    }
};

 

用一个数组last[256]记录该字符上一次出现的位置,如last['a'] = 1,代表a上次出现在1的位置,

然后依次遍历整个字符串,如果再次出现该字符就减去上一次出现的位置,即可得到长度,再更新last数组,

遍历完了就得到最长的无重复的字符串了

以abca为例: 
i=0:查表last[‘a’] = -1,①不执行 idx=-1, ②执行max =1,更新last表 last[‘a’] = 0; 
i=1:查表last[‘b’] = -1,①不执行 idx=-1, ②执行max =2,更新last表 last[‘b’] = 1; 
i=2:查表last[‘c’] = -1,①不执行 idx=-1, ②执行max =3,更新last表 last[‘c’] = 2; 
i=3:查表last[‘a’] = 0,①执行,idx=0 , ②执行max =3,更新last表 last[‘a’] = 3; 
….. 
上述算法的时间复杂度为O(n),Accepted!

posted @ 2016-04-21 20:15  雪之灵  阅读(212)  评论(0编辑  收藏  举报