📅  最后修改于: 2023-12-03 14:49:32.577000             🧑  作者: Mango
题目描述:
给定一个字符串,请找出其任意两次出现之间的最长子字符串,满足该子字符串中相似字符的数量不少于k。其中,相似字符是指ASCII码值差值不超过1的字符。
算法思路:
时间复杂度:O(n)
空间复杂度:O(n)
代码实现:
def find_longest_substring(s: str, k: int) -> str:
sim_chars = [] # 存储相似字符组的起始位置和相似字符数
sim_char_index = {} # 存储相似字符组的最后一次出现位置
i, length = 0, len(s)
while i < length:
# 相邻且ASCII码值差值不超过1的字符组成一个相似字符组
j = i
while j + 1 < length and abs(ord(s[j+1]) - ord(s[j])) <= 1:
j += 1
sim_chars.append((i, j - i + 1))
i = j + 1
longest_substring, current_substring = "", ""
for i, (start, sim_char_cnt) in enumerate(sim_chars):
# 如果相似字符组中的字符数不少于k
if sim_char_cnt >= k:
if current_substring:
# 从当前位置开始,到相似字符组的结束位置为止,最大化字符串长度
for j in range(start, sim_chars[i-1][0] + sim_chars[i-1][1]):
if j in sim_char_index and sim_char_index[j] >= sim_chars[i-1][0]:
sim_char_cnt += 1
# 更新相似字符组最后一次出现的位置
sim_char_index[j] = sim_chars[i-1][0] + sim_chars[i-1][1] - 1
# 如果相似字符组中的字符数不小于k,则更新最长子字符串长度
if sim_char_cnt >= k and len(current_substring) > len(longest_substring):
longest_substring = current_substring
current_substring = s[start:start + sim_char_cnt]
else:
if current_substring:
current_substring += s[start:start + sim_char_cnt]
return longest_substring
注意事项: