zoukankan      html  css  js  c++  java
  • Leetcode 3 Longest Substring Without Repeating Characters

    1.题目要求

    Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

    2.分析

    读懂题目之后,脑海中出现的第一个解决方法就是遍历字符串s,当某个字符在比它靠前的字符串s1中出现过时,按照如下方法处理:

    假设初始字符串s,两个下标i,j,从头开始扫描,当扫描到j+1时,s[j+1]属于s[0……j],注意s[0……j]中的字符都不相同。假设s[i]=s[j+1],result = j-0+1;接下来说明如果存在满足条件并且比result大的子串,一定是从s[i+1]开始往后的子串。

    因为s[i]=s[j+1],因此,任意一个以s[1……i]一个字符开始的子串,并且满足题目要求的串都终止与s[j],其长度必然小于result。如果想要找到一长度大于result并且满足要求的子串,必然要从s[i+1]开始往后寻找。

    代码如下:

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            int res=0,i=0,j=0;
            int length = s.length();
            if (0 == length)
            {
                return 0;
            }
            set<char> mySet;
            mySet.clear();
            while (j<length)
            {
                if(mySet.find(s[j]) == mySet.end())
                {
                    mySet.insert(s[j]);
                    j++;
                }
                else
                {
                    if(j-i > res)res = j-i;
                    mySet.clear();
                    i++;
                    j=i;                
                }
            }
            if(j-i > res)res = j-i;
            return res;
        }
    };

    提交答案。Time Limit Exceeded。悲伤啊。

    重新判断这个算法,我们会发现,算法会产生回溯,也就是j被赋值为i时,导致回溯,算法时间复杂度最坏情况是O(2n)。因此我们需要想办法避免这个多余的开销,保证j在前进的方向永不回头。

    在上述方法中,当发现s[i]=s[j+1]时,我们是采取把下标j往回移动,我们可以换一个角度,将start往后移动到i+1处,这里需要注意啊,start在移动的时候,需要将s[start]从set中剔除。这个算法需要保存好之前出现的字符的下标

    代码如下:

     1 class Solution {
     2 public:
     3     int lengthOfLongestSubstring(string s) {
     4         int res=0;
     5         int length = s.length();
     6         if (0 == length)
     7         {
     8             return 0;
     9         }
    10         int i=0,j=1;
    11         int index[256];
    12         memset(index,-1,sizeof(index));
    13         index[s[0]]=0;
    14         while (i<j&&j<length)//"abcabcbb"
    15         {
    16             if(-1 == index[s[j]])
    17             {
    18                 index[s[j]]=j;    
    19 
    20             }
    21             else
    22             {
    23                 if(j-i>res)res = j-i;
    24                 while(true)
    25                 {
    26                     if (s[i]!=s[j])
    27                     {
    28                         index[s[i]]=-1;
    29                         i++;                        
    30                     }else
    31                         break;
    32                     
    33                 }
    34                 i++;
    35             }
    36             j++;
    37 
    38 
    39         }
    40         if(j-i>res)res = j-i;
    41         return res;
    42     }
    43 };

    提交代码,Accepted。

  • 相关阅读:
    把java程序作为windows服务运行
    安装CentOS7出现dracut-initqueue timeout-starting…starting timeout scripts 解决办法
    在Linux下打包tar文件时添加密码的方法
    tk mybatis通用mapper,复杂and or条件查询
    firewalld 端口转发(机器内转发+机器间转发)
    postgresql中的序列nextval
    postgresql 建立索引
    索引面试题分析
    PostgreSQL不等于查询索引方法
    net-snmp开发中出现“Error opening specified endpoint"" ”的解决方案
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/4375922.html
Copyright © 2011-2022 走看看