• 【字符串】最长不重复子串


    参考资料:

              http://www.ahathinking.com/archives/123.html 

    题目:

           从一个字符串中找到一个连续子串,该子串中任何两个字符不能相同,求子串的最大长度并输出一条最长不重复子串

    思路:

           使用一个数组dp[i]记录到当前下标i的元素为止,最长的不重复子串长度。使用lastIndex记录上一个最长不重复子串的开始位置,

    使用before表示当前元素重复出现的上一个位置,那么有如下的状态方程:

    image

    void lnrs_1(const char *s ,int size)
    {
        int visit[256]={0};        //记录上一次元素出现下标
        memset(visit,-1,256*4);
        int *dp=new int[size];    //至下标为i的元素的最长不重复子串长度
        memset(dp,0,size*4);
    visit[s[0]]=0;
    dp[0]=1;
    int endIndex=0; //最长不重复子串结束下标 int maxlen=0; //最长不重复子串长度 int lastIndex=0; //上一个不重复子串的开始位置 for(int i=1;i<size;i++) { if(visit[s[i]]==-1) //当前元素未重复出现 { dp[i]=dp[i-1]+1; visit[s[i]]=i; } else { if(lastIndex > visit[s[i]]) { dp[i]=dp[i-1]+1; } else { dp[i]=i-visit[s[i]]; lastIndex=visit[s[i]]+1; } visit[s[i]]=i; } if(dp[i] > maxlen) { maxlen=dp[i]; endIndex=i; } } cout<<"index:"<<endIndex-maxlen+1<<","<<endIndex<<endl; delete[] dp; }

    改进版本:

          考虑上上述实现,dp[i]表示下标为i的元素为止的最长重复子串,dp[i]的作用是更新maxlen(最长不重复子序列长度),可以使用curlen

    表示至当前元素的最长不重复子串的长度,用于更新maxlen。

    算法时间复杂度:O(n),空间复杂度O(1)

    void  lnrs(const char *s,int size)
    {
        int visit[256];    //记录当前元素上一次重复出现的位置
        memset(visit,-1,256*4);
        visit[s[0]]=0;
        int endIndex=0;      //最长不重复子串结尾位置
        int maxLen=0;        //最长不重复子串长度
        int lastIndex=0;  //上一个不重复子串的开始位置
        int curlen=1;     //至当前元素不重复子串的长度
    
        for(int i=1;i<size;i++)
        {
            if(visit[s[i]]==-1)
            {
                curlen++;
                visit[s[i]]=i;
            }
            else
            {
                if(lastIndex > visit[s[i]])
                {
                    curlen++;
                }
                else
                {
                    curlen=i-visit[s[i]];
                    lastIndex=visit[s[i]]+1;
                }
                visit[s[i]]=i;
            }
    
            if(curlen > maxLen)
            {
                maxLen=curlen;
                endIndex=i;
            }
        }
        cout<<"maxIndex:["<<endIndex-maxLen+1<<","<<endIndex<<"]"<<endl;
    }
  • 相关阅读:
    try-with-resources优先于try-finally
    创建和销毁对象——避免创建不必要的对象
    创建和销毁对象——用私有构造器或者枚举类型强化Singleton属性
    创建和销毁对象——遇到多个构造器参数时考虑使用构建器
    创建和销毁对象——用静态工厂方法代替构造器
    计算机网络物理层——数据通信的基础知识
    多线程——线程交互
    多线程——同步问题
    Percona Monitoring and Management (PMM)
    Docker
  • 原文地址:https://www.cnblogs.com/luosongchao/p/3684171.html
Copyright © 2020-2023  润新知