给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
1 |
|
示例 2:
1 |
|
示例 3:
1 |
|
思路一
使用双重循环和一个hash表来实现,双重循环遍历所有的子串,hash表记录是否出现重复,时间复杂度 $O(n^2)$。
需要注意的是长度为0和1的串以及子串的最后一个字符的判断。
1 |
|
思路二
使用hash表存放每个字符在串中的位置。
使用两个指针,一个指向子串的开头,另一个后移并判断指向的字符是否出现过,如果出现过,如果此时子串的开头指针位置在已出现的字符位置之前,则表示出现重复,则子串开头指针后移,否则计算子串的长度。
时间复杂度 $O(n)$。
1 |
|
思路三
使用动态规划的思想,令 $l[i] = s[m\dots i]$ 表示串 $s$ 在 $s[i]$ 处结尾的没有重复字符的最长子串,同时我们使用一个hash表存放已出现字符的位置。当处理 $s[i+1]$ 时:
- 如果 $s[i+1]$ 没有在hash表中 出现,我们可以直接将 $s[i+1]$ 添加到hash表,并且 $l[i+1] = s[m\dots i+1]$;
- 如果 $s[i+1]$ 在hash表中出现,并且hash值(即已出现字符的下标)为 $k$,则令 $m = \max(m, k)$,$l[i+1] = s[m\dots i+1]$,同时更新hash表中 $s[i+1]$ 的值为最新的出现位置。
时间复杂度 $O(n)$。
1 |
|