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一下,想到了再改。

原文地址:https://www.cnblogs.com/AI-U/p/10432473.html