Leetcode 3-最长无重复子串

题目:

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring"pwke" is a subsequence and not a substring.

分析:

也就是找不含重复字母的子串的最大长度。可以用滑动窗口的思想,每个窗口有一个start位置,窗口长度可以随着遍历增长;按顺序一个个字母移动,如果第i个字母已经在从start到i的子串中出现了,那么可以计算从start--> i-1位置的长度,如果足够大,即保存为最新的maxlength;并且窗口要向下滑动,以第i个字母在子串中出现过的位置的下一个作为新的start;如果遍历的是没出现过的字母,计算当前子串的长度,检查是否要更新maxlength


举个例子,abac ,一开始start设为0,maxlength设为0,开始遍历,第一个到'a',从没有出现过,当前子串长度为1,更新'a'上次出现的位置为索引0;i=1时遍历到‘b’,也没出现过,子串现在长度为2;i=2时字母‘a’,上次出现的位置是0处,在当前判断的子串范围内(0-2),所以start要变成1(滑动窗口向下滑动,过滤掉开始的字母'a');继续i=3,此时计算从start位置开始的子串长度为3


那么怎么快速查看当前字母是否在当前滑动窗口所含子串里呢?可以用map<char,int>,记录字母char上次出现的位置,然后与start比较,是否是在当前考虑的子串中


代码:

 int lengthOfLongestSubstring(string s) {
     map<char,int>mapp;
     int length = s.length();
     int start = 0;int maxlen = 0;
     for(char i = 'a';i<='z';i++)mapp[i]=-1;//初始化,只初始化小写字母也过了,可能是样例不含大写字母
     for(int i = 0;i<length;i++)
     {
         if(mapp[s[i]]>=start)//当前遍历到的字母在现在考虑的子串中出现过了
         {

             start = mapp[s[i]]+1;//start设为出现过的那一字母的下一位置,也就是过掉重复字母
             mapp[s[i]]=i;//记录该字母出现的位置为下一次所用
         }
         else{//没出现过
                mapp[s[i]]=i;//记录出现的位置
                int t = i-start+1;//记录目前从start位置开始的子串长度
            maxlen = (maxlen<t)?t:maxlen;
         }
     }
     return maxlen;
    }

几个样例:

abcabcbb

abcabc

a

ab

aab

tmmzuxt

猜你喜欢

转载自blog.csdn.net/beforeeasy/article/details/79627442