• LeetCode Longest Substring Without Repeating Characters 最长不重复子串


    题意:给一字符串,求一个子串的长度,该子串满足所有字符都不重复。字符可能包含标点之类的,不仅仅是字母。按ASCII码算,就有2^8=128个。

    思路:从左到右扫每个字符,判断该字符距离上一次出现的距离是多少,若大于max,则更新max。若小于,则不更新。每扫到一个字符就需要更新他的出现位置了。这里边还有个注意点,举例说明:

    假如有长为16串 s="arbtbqwecpoiuyca

    当扫到第2个b时,距离上一个b的距离是2;(直接减)

    当扫到第2个c时,距离上一个c的距离是6;(直接减)

    但是!当扫到第2个a时,距离上一个a的距离是15,可是这串里面已经有b和c都有重复的了,是不符合的。真正的长 = 第2个a的位置 - 第1个c的位置。

    假设当前扫到的字符为'A',其实求长的式子应该这样的:len = i - max(cur,pos[A])    

    这里的cur是指一个字符的位置,该字符是距离A最近的,并且在该字符与A之间还会出现该字符一次,(也就是在两个A之间,如果有出现次数为两次的字符,记录下第1个字符的位置,若多次出现,记录从右数第2次出现该字符的位置)这个cur的值要随时更新。

    注:坑!这个算法的复杂度完全的O(n),实在强大。想了2天,我本来想到用哈希来做,感觉有点麻烦,一直在想更简单的,下面这个别人的代码实在简洁到没办法了,佩服。

     1 class Solution {
     2 public:
     3     int lengthOfLongestSubstring(string s) {
     4         // Start typing your C/C++ solution below
     5         // DO NOT write int main() function
     6         int locs[256];//保存字符上一次出现的位置
     7         memset(locs, -1, sizeof(locs));
     8 
     9         int idx = -1, max = 0;//idx为当前子串的开始位置-1
    10         for (int i = 0; i < s.size(); i++)
    11         {
    12             if (locs[s[i]] > idx)//如果当前字符出现过,那么当前子串的起始位置为这个字符上一次出现的位置+1
    13             {
    14                 idx = locs[s[i]];
    15             }
    16 
    17             if (i - idx > max)
    18             {
    19                 max = i - idx;
    20             }
    21 
    22             locs[s[i]] = i;
    23         }
    24         return max;
    25     }
    26 };
    Longest Substring Without Repeating Characters

    上面代码一字不差复制过来了。

  • 相关阅读:
    2009下半软考信息系统项目管理师,我又没通过。
    批量文件渲染
    Python Trick
    QThread basic
    一个简单的进度条
    js 基础知识回顾
    前端 知识笔记
    jquery 回顾
    Sass 回顾
    css
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4399601.html
Copyright © 2020-2023  润新知