• LeetCode刷题计划——3.无重复字符的最长子串


    给定一个字符串,求一个最长子串,子串中没有重复字符,输出子串长度。(假设子串均以小写字母表示)


    由于最长子串肯定大于等于1,所以从长度为2的开始判断即可。除非给空串

    思路一:穷举遍历

    两个嵌套循环,从第i=0,j=i+1开始,遍历所有子串,判断每一个子串是否有重复字符,如果没有,将当前子串长度与存储当前最长子串长度的临时变量对比,取最大值(初始为1)。

    相当于三重嵌套,时间复杂度O(n3),空间复杂度O(1).

    思路二:滑动窗口

    思路一中,在遍历 j 时,如果 i~j 出现了重复, j 之后就没有必要再遍历了。 从 i + 1 开始重新遍历即可。

    这样思路就转换成了,找 i 开头的最长子串, 每个 i 都找完后, 就可得到最终结果。

    这样,时间复杂度首先降低为了O(n2)。

    而且 i ~ j 出现了重复,  元素 k 与 j 重复, i <= k < j, 那么以 i ~ k 之间元素开头的子串长度肯定比 i 开头的子串短,因为后边有重复元素 j 。

    所以直接跳到 查找 k+1开头的元素即可。

    使用HashMap作为滑动窗口,如果不重复,则窗口右边界扩充1,如果重复,窗口左边界缩小至重复元素k,右边界保持不动。如此重复,直至右边界到达字符串末尾。

    时间复杂度O(n), 空间复杂度O(m), m为256,可见字符为char,一共256个。


    拓展:如果最长子串不是一个,而是有可能有多个,试输出所有满足条件的最长子串。

    首先找最长子串长度n,然后使用固定长度为n的滑动窗口。

    时间复杂度O(2n),空间复杂度O(m+n)


     拓展:如果上述拓展中,要求去重,怎么办?

    暂时没想到特别好的方法,先Mark一下,想到了再改。

  • 相关阅读:
    Jzoj3555 树的直径
    Jzoj3555 树的直径
    51Nod1022 石子归并V2
    51Nod1022 石子归并V2
    Bzoj3998 弦论
    Bzoj3998 弦论
    Poj2758 Checking the Text
    Poj2758 Checking the Text
    常用SQL语句大全
    Silverlight调用GP服务第二篇之调用GP服务(Geoprocessing Service)过程详解
  • 原文地址:https://www.cnblogs.com/AI-U/p/10432473.html
Copyright © 2020-2023  润新知