我目前正在准备一次技术面试,并用Python练习一些数据 struct 和算法问题.有一个常见问题要求您查找字符串中最长的子字符串,以便该子字符串不包含重复字符.凭直觉,我知道如何使用滑动窗口来解决这个问题,这可以通过以下方式实现:

def longest_substring(s: str) -> int:
    
    longest_sub_string = 0
    
    if len(s) == 1:
        return 1
    
    for window_size in range(len(s) + 1, 0, -1):
        for i in range(len(s) - window_size + 1):
            window = s[i:i+window_size]
            if not self.contains_repeats(window) and len(window) > longest_sub_string:
                longest_sub_string = len(window)
    return longest_sub_string
    
    
def contains_repeats(s: str = None) -> bool:
    
    splt = list(s)
    if len(list(set(splt))) < len(splt):
        return True

然而,对于需要O(n^2)时间的很长输入字符串,这种解决方案并不有效.我发现了另一种滑动窗口实现:

def longest_substring(s: str) -> int:
    
    last_idxs = {}
    max_len = 0
    
    start_idx = 0
    
    for i in range(0, len(s)):
        
        if s[i] in last_idxs:
            start_idx = max(start_idx, last_idxs[s[i]] + 1)
        
        max_len = max(max_len, i-start_idx + 1)
        
        last_idxs[s[i]] = i
        
    return max_len

它在线性时间内解决了这个问题.我已经分清了代码的作用,理解了各个部分,但无法将其与滑动窗口的工作方式联系起来,这使我无法将这种方法应用于不同的问题.我可以只记住代码,但我想了解第二个代码块中发生的事情与第一个代码块中发生的事情是如何相似的.有谁能用一种直截了当的方式来解释这一点,说明第二种变体是如何实现滑动窗口的?

推荐答案

我不会把第一个代码称为"滑动窗口算法".它似乎只是一个try 所有可能的子字符串的bruteforce算法.这可能需要与n³成比例的时间,因为需要判断n²子串,在最坏的情况下,应用contains_repeats可能需要与每个子串的n成比例的时间.或者更确切地说,如果k是字母表中不同字符的数量,那么contains_repeats可能需要与min(n,k)成比例的时间;因此,第一种算法最多需要n² min(n, k)分钟.

第二种算法是滑动窗口算法.窗口从索引start_idx转到索引i.这需要与n成正比的时间,因为这两个指标中的每一个都只能增加,而不能减少,所以总迭代次数最多为2n.这些算法没有try 所有可能的子字符串,而是有一个大小不同的"窗口",从左到右"滑动"(并且永远不会返回).

请注意,"滑动窗口算法"是一个至少有两种不同含义的术语.除了这种字符串算法之外,它有时还用来指使用卷积的算法.

Python相关问答推荐

PyTorch卷积自动编码器,输出维度与输入不同

Django序列化器没有验证或保存数据

Plotly:如何更改Heatmap中彩色条的勾选文本

使用argsorted索引子集索引数组

DuckDB将蜂巢分区插入拼花文件

在Pandas 日历中插入一行

使用FASTCGI在IIS上运行Django频道

韦尔福德方差与Numpy方差不同

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

rame中不兼容的d类型

非常奇怪:tzLocal.get_Localzone()基于python3别名的不同输出?

查找两极rame中组之间的所有差异

C#使用程序从Python中执行Exec文件

如何在Python脚本中附加一个Google tab(已经打开)

Streamlit应用程序中的Plotly条形图中未正确显示Y轴刻度

在pandas中使用group_by,但有条件

Django admin Csrf令牌未设置

跳过嵌套JSON中的级别并转换为Pandas Rame

使用嵌套对象字段的Qdrant过滤

Python将一个列值分割成多个列,并保持其余列相同