[剑指Offer]48-最长不含重复字符的子字符串

时间:2019-03-19
本文章向大家介绍[剑指Offer]48-最长不含重复字符的子字符串,主要包括[剑指Offer]48-最长不含重复字符的子字符串使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意

如题,字符串只含a-z,输出该子串长度。例:"arabcacfr",输出4。

解题思路

动态规划思想?

  • 计f(i)为以第i个字符结尾的最长不含重复字符的子串长度
  • 状态转移:计d为当前字符出现位置和上次出现该字符的位置之差。

(1) 当d>f(i-1),说明字符出现在f(i-1)对应的最长子串外,所以f(i)=f(i-1)+1。

(2) d<=f(I-1),说明字符出现在f(i-1)对应的最长子串中,此时说明当前字符与上次出现的改字符之间无重复字符,所以f(i)=d;

用循环实现。
时间复杂度O(n).

代码

#include <iostream>
#include <string>
using namespace std;

int subStrLen(string s){
    if(!s.size()){
        return 0;
    }
    
    int lastAppear[26];
    memset(lastAppear,-1,sizeof(lastAppear));
    
    int tempLen=0;
    int maxLen=0;
    for(int i=0;i<s.size();++i){
        if(i==0){
            tempLen=1;
        }
        else{
            int lastIdx=lastAppear[s[i]-'a'];
            if(lastIdx==-1){
                tempLen+=1;
            }
            else if((i-lastIdx)>tempLen){
                tempLen+=1;
            }
            else{
                tempLen=i-lastIdx;
            }
        }
        
        lastAppear[s[i]-'a']=i;
        if(tempLen>maxLen){
            maxLen=tempLen;
        }
    }
    return maxLen;
}

int main(int argc, const char * argv[]) {
    string s="arabcacfr";
    int len=subStrLen(s);
    cout<<len<<endl;
    return 0;
}