最长重复子串返回最大长度395. 每个字符至少重复 K 次的最长子串Medium/ 424. 最多替换 K 次后的最长重复子串Medium/ 非重复串问题【题目链接】最长不含重复字符的子字符串动态规划 / 双指针 哈希表清晰图解代码classSolution:### 1104 动态规划 哈希表 O(N)64 ms13.4 MBdeflengthOfLongestSubstring(self,s:str)-int:dic,res,tmp{},0,0# tmp表示前一时刻最长不含重复字符的子字符串的长度初始化为0forjinrange(len(s)):# 遍历字符串中每一个字符idic.get(s[j],-1)# 获取下标idic[s[j]]j# 更新某个字符s[j]出现的最新位置j下标更新哈希表tmptmp1iftmpj-ielsej-i# dp[j - 1] - dp[j]resmax(res,tmp)# 更新最大值returnres### 1104 动态规划 线性查找 O(N2)484 ms13.6 MBdeflengthOfLongestSubstring(self,s:str)-int:restmp0# tmp表示前一时刻最长不含重复字符的子字符串的长度初始化为0forjinrange(len(s)):# 遍历字符串中每一个字符ij-1# 初始化下标i将i初始化为j左边的值whilei0ands[i]!s[j]:i-1# 从右往左更新i逆序tmptmp1iftmpj-ielsej-i# dp[j - 1] - dp[j]resmax(res,tmp)# 更新最大值returnres### 1104 动态规划 双指针 O(N)68 ms13.6 MBdeflengthOfLongestSubstring(self,s:str)-int:dic,res,i{},0,-1# 初始化左指针i为-1forjinrange(len(s)):# 遍历字符串中每一个字符ifs[j]indic:# 检查当前字符是否在哈希表中imax(dic[s[j]],i)# 若存在则更新左指针idic[s[j]]j# 更新某个字符s[j]出现的最新位置j下标更新哈希表resmax(res,j-i)# 更新最大值returnres返回最长无重复字符的子串【对应上面方法3双指针】直接用这个同时返回子字符串和长度2026.4# 双指针classSolution:deflengthOfLongestSubstring(self,s):max_len0max_subifnots:returnmax_sub,max_len# 滑动窗口使用左指针 left 和右指针 right 维护一个窗口窗口内字符都不重复left0# 哈希表集合char_set 记录当前窗口中的字符用于快速判断重复char_setset()forrightinrange(len(s)):# 若当前字符已经在窗口内移动左指针直到重复字符被移出whiles[right]inchar_set:char_set.remove(s[left])left1# 将当前字符加入窗口char_set.add(s[right])curr_lenright-left1# 更新结果每次窗口合法后计算当前长度# 若大于已记录的最大长度则更新最大长度和对应的子串ifcurr_lenmax_len:max_lencurr_len max_subs[left:right1]# print(f长度: {max_len}, 子串: {max_sub})returnmax_sub,max_len1044. 最长重复子串返回任一子串题解classSolution:deflongestDupSubstring(self,s:str)-str:ansmax_len,start,end,n0,0,1,len(s)# 每次看s[start:end]在之后s[start1:]是否也出现因为在s[start:]肯定出现一次所以总共出现次数2# 出现的话更新max_len,同时end后移看更长的是否满足# 不出现的话表明以start开头的子串不可能出现2次start后移whileendn:ifs[start:end]ins[start1:]:# 判断子串出现至少两次# 如果子串长度超过当前最大值更新最大值和ansifmax_lenend-start:max_lenend-start anss[start:end]end1continuestart1returnans