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

    题意很简单,就是寻找一个字符串中连续的最长包含不同字母的子串。

    其实用最朴素的方法,从当前字符开始寻找,找到以当前字符开头的最长子串。这个方法猛一看是个n方的算法,但是要注意到由于字符数目的限制,其实这是个O(Cn)的算法,最长也不过是C长度。所以我觉得普通方法应该是能过的。

    于是写了一个,字符数目最大也不超过256所以代码如下:

     1 class Solution {
     2 public:
     3     int lengthOfLongestSubstring(string s) {
     4 
     5         int res=0;
     6         for(int i=0;i<s.length();i++)
     7         {
     8             int flag[200];
     9             memset(flag,0,sizeof(flag));
    10             int count = 0;
    11             flag[s[i]-' '] = 1;
    12             int tempres = 1;
    13             for (int j = i + 1; j < s.length(); j++) {
    14                 if (flag[s[j]-' ']==0) {
    15                     flag[s[j]-' ']= 1;
    16                     tempres++;
    17                 } else
    18                     break;
    19             }
    20             if (tempres > res)
    21                 res=tempres;
    22         }
    23         return res;
    24     }
    25 };

    其中空格是ASCII码第一个实际意义字符,所以减去‘ ’

    正常的O(n)方法是使用哈希表来存已经出现的字符,使用一个指针依次检索,如果碰到已经存在的字符,则去使用第二个指针更新这个哈希表。

    从原理上来具体讨论双指针这个算法,对于第一个指针指到的字母有两种情况:

    1.从来没有使用过

    当前长度加一,将这个位置和字母加入哈希表,第二个指针不动

    2.已经使用过,并且有一个哈希表存这个字母的上一个位置

    获取上一个位置右侧位置(+1操作),将这个位置和第二个指针比较,

    (1)如果小于第二个指针,说明以当前结尾的字符串在第j个指针的地方有字母重复,忽略这个位置,继续以j为准

    (2)如果大于第二个指针,说明以当前结尾的字符串在这个最新的位置有重复,将指针移到这个位置,计算这个长度。

    这三种情况涵盖了所有可能,并在下面的例子中有相应出现。

    代码:

    此代码来自最多discuss区最多vote的答案:https://leetcode.com/discuss/23883/11-line-simple-java-solution-o-n-with-explanation

     1 public int lengthOfLongestSubstring(String s) {
     2         if (s.length()==0) return 0;
     3         HashMap<Character, Integer> map = new HashMap<Character, Integer>();
     4         int max=0;
     5         for (int i=0, j=0; i<s.length(); ++i){
     6             if (map.containsKey(s.charAt(i))){
     7                 j = Math.max(j,map.get(s.charAt(i))+1);
     8             }
     9             map.put(s.charAt(i),i);
    10             max = Math.max(max,i-j+1);
    11         }
    12         return max;
    13     }

    例子:

    对于这个字符串:abcbcda

    经过初始化循环执行过程如下:

    i=0;  j=0;  (a,0)  max(0,1)=1  第一种情况

    i=1;  j=0;  (b,1)  max(1,2)=2  同上

    i=2;  j=0;  (c,2)  max(2,3)=3  同上

    i=3;  j=(0,1+1)=2;  (b,3)  max(3,2)=3  第二种第二个情况

    i=4;  j=(2,2+1)=3;  (c,4)  max(3,2)=3  同上

    i=5;  j=3;  (d,5)  max(3,3)=3  第一种情况

    i=6;  j=(3,1)=3;   (a,6)  max(3,4)=4  第二种第一个情况

         

  • 相关阅读:
    数据缓存/NSURLSession
    NSURLConnection基本使用/多线程断点下载/文件的上传
    HTTP协议/数据安全
    block的概念及基本使用 /block访问外部变量
    NSOperation简单介绍/NSOperation基本操作/自定义NSOperation
    GCD介绍/GCD的基本使用/GCD的常见用法
    NSThread方式创建线程/线程安全/线程间的通信
    面试常见知识点
    新课堂练习题
    线程概述
  • 原文地址:https://www.cnblogs.com/holyprince/p/4606343.html
Copyright © 2011-2022 走看看