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。

  • 相关阅读:
    ASP.NET Web API 中 特性路由(Attribute Routing) 的重名问题
    在 ASP.NET Web API 中,使用 命名空间(namespace) 来作为路由的参数
    【转】使用create_project.py创建cocos2d项目时出错
    WCF使用net.tcp绑定时的注意事项
    WCF:如何将net.tcp协议寄宿到IIS
    关于WCF服务的调试跟踪
    Windows Store Apps 开发转载
    如何让弹出窗口和页面产生联动?
    关于C# wpf DataGrid单元格双击设置单元格内容
    在WPF的DataGrid中对行添加单击事件
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/4375922.html
Copyright © 2011-2022 走看看