[LeetCode] 3. Longest Substring Without Repeating Characters 题解

问题描述

输入一个字符串,找到其中最长的不重复子串

例1:

输入:"abcabcbb"
输出:3
解释:最长非重复子串为"abc"

例2:

输入:"bbbbb"
输出:1
解释:最长非重复子串为"b"

例3:

输入:"pwwkew"
输出:3
解释:最长非重复子串为"wke"

问题难度

Medium

解题思路

本题采用「滑动窗口法」可以达到较理想的时间复杂度 O(n),滑动窗口指的是当前非重复子串所在的窗口,此滑动窗口有两种操作方法

  1. 检查下一个字符是否会重复,如未重复,则将窗口向右扩大
  2. 发现重复字符,则将窗口右边界保持不变,左边界右移,以此缩小窗口

上面的操作比较容易理解,唯一需要注意的是第 2 点中,当发现重复字符时,窗口左边界向右移动几个单位,我们可以看一个示意图:

+---------+ 
| a b c d | e d x y z 
+---------+
 
+-----------+ 
| a b c d e | d x y z // 未发现重复,向右扩大窗口
+-----------+

        +-----+ 
a b c d | e d | x y z // 发现重复,缩小窗口
        +-----+

假设输入字符串为 "abcdedxyz",一直到我们遍历到字符 e 时,均未发现重复的字符串,至此对窗口进行的操作都是向右扩大,当检查到下一个字符 d 时,由于前面字符串中已经出现过该字符,所以窗口左边界需要进行右移,移动的位置、即新子串窗口的起始点,正好是两个重复字符中、第一个重复字符的右边,如图所示为字符 e 所在的位置。

至此,我们可以开始写程序了:

def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        maxlen = 0
        current_substring = [None]*128
        current_substring_len = 0
        begin_index = 0
        for i in s:
            stoi = ord(i)
            if current_substring[stoi] is None or current_substring[stoi] < begin_index:
                current_substring[stoi] = begin_index + current_substring_len
                current_substring_len += 1
            else:
                if maxlen < current_substring_len:
                    maxlen = current_substring_len 
                
                sub_len = current_substring[stoi] - begin_index + 1
                begin_index = current_substring[stoi] + 1
                current_substring_len -= sub_len

                current_substring[stoi] = current_substring_len + begin_index
                current_substring_len += 1

        if maxlen < current_substring_len:
            maxlen = current_substring_len
        return maxlen

以上代码中,current_substring 是一个缓冲区,用来存放当前子字符串,缓冲区声明为 128 个是为了让数组的下标空间能容纳 128 个 ASCII 字符,即这里用数组的下标来表示字符,这样做的好处是可以很快的知道某个字符是否出现重复,数组的内容我们填的是该字符对应的下标,例如字符串 "abcde" 填到 current_substring 中为:

            index:   0..97  98  99  100 101 ..
                   +---+---+---+---+---+---+---+
current_substring: |...| 0 | 1 | 2 | 3 | 4 |...|
                   +---+---+---+---+---+---+---+

我们用变量 begin_index 来记录当前窗口在字符串中的起始位置,而 current_substring_len 用来记录当前窗口的长度。for 循环是对字符串的遍历。

首先将字符转化为其对应的整数 stoi,检查 stoi 中的内容是否为空,或其存储的位置是否在窗口的左边,如是则表示该字符在 begin_index 之后未出现过,非重复子串可以继续累加。

否则表示出现重复,出现重复时,需要将窗口的左边界右移,或者说对新的滑动窗口进行初始化,实际上只需更新 begin_indexcurrent_substring_len 两个值。

最后,我们需要在每一次窗口改变时,或在结束遍历时,判断当前子字符串的长度是否是最长的,并将最长串存储在 maxlen 中,作为结果返回。

原题链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容