这是我第一次的面试题,再做是否有一些思路?拿老板的说法:你成长了吗
解题思路:
长度为n的字符串共有(n+1)n/2个子串,用暴力法O(n^3),因此用dp降低时间复杂度
解法一:dp+hash表 时间复杂度O(n),空间复杂度O(1)
哈希表统计: 遍历字符串 ss 时,使用哈希表(记为 dicdic )统计 各字符最后一次出现的索引位置 。
左边界 ii 获取方式: 遍历到 s[j]s[j] 时,可通过访问哈希表 dic[s[j]]dic[s[j]] 获取最近的相同字符的索引 ii
空间复杂度 O(1): 字符的 ASCII 码范围为 00 ~ 127127 ,哈希表 dicdic 最多使用 O(128) = O(1) 大小的额外空间
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 暴力解法o(n^3)),用哈希表进行剪枝(索引为字符,值为序列,o(1)就能找到最近相同字符)最值,存在,可以用dp。dp就是用空间换时间。dp方程为dp[j]=min(dp[j-1]+1,j-i)。综上,o(n),o(1))
dic,res,tmp={},0,0
for j in range(len(s)):
i=dic.get(s[j],-1)
dic[s[j]]=j
tmp=tmp+1 if tmp+1<j-i else j-i
res=max(tmp,res)
return res
解法二:滑动窗口(双指针) 时间复杂度O(n),空间复杂度O(1) (与·解法一不同在于左边界i的定义)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
dict = {}#指针j遍历字符s ,哈希表统计字符 s[j]最后一次出现的索引 。
res,i = 0,-1
for j in range(len(s)):
i = max(dict[s[j]],i)# 更新左边界i,保证区间 [i + 1, j]内无重复字符且最大
dict[s[j]] = j# 哈希表记录
res = max(res,j - i) #取上轮 resres 和本轮双指针区间 [i + 1,j][i+1,j] 的宽度(即 j - ij−i )中的最大值
return res