📜  扩张和全局滑动窗口注意(1)

📅  最后修改于: 2023-12-03 15:39:43.341000             🧑  作者: Mango

扩张和全局滑动窗口注意

简介

扩展和全局滑动窗口技术是处理字符串和数组的经典算法之一。它们用于解决许多问题,包括最小窗口子串,子串,回文和滑动窗口的问题。

扩张法

扩张法是一种常用的字符串处理技术。它的基本思想是从左到右扫描字符串,以每个位置为中心,向左右两个方向扩展,以确定最长的回文。

时间和空间复杂度

扩张法的时间和空间复杂度都为$O(N^2)$。在最坏情况下,需要扩展N次,每次都需要O(N)的时间,因此运行时间是$O(N^2)$。

代码示例
def expand(center, left, right, s):
    while left >= 0 and right < len(s) and s[left] == s[right]:
        left -= 1
        right += 1
    return right - left - 1

def longest_palindrome(s: str) -> str:
    if len(s) < 1:
        return ""
    start, end = 0, 0
    for i in range(len(s)):
        len1 = expand(i, i, i, s)
        len2 = expand(i, i, i+1, s)
        length = max(len1, len2)
        if length > end - start:
            start = i - (length - 1) // 2
            end = i + length // 2
    return s[start:end+1]
全局滑动窗口

全局滑动窗口是一种常用的数组处理技术。它的基本思想是维护一个窗口,使其滑动到数组的尽头,同时保持窗口中的特定条件。

时间和空间复杂度

全局滑动窗口的时间复杂度为$O(N)$。它只需要在数组上执行一次线性扫描。空间复杂度也为$O(N)$。

代码示例
def min_window(s: str, t: str) -> str:
    need, window = collections.Counter(t), {}
    left, right = 0, 0
    valid = 0
    start, length = 0, float('inf')
    
    while right < len(s):
        c = s[right]
        right += 1
        if c in need:
            window[c] = window.get(c, 0) + 1
            if window[c] == need[c]:
                valid += 1
        while valid == len(need):
            if right - left < length:
                start = left
                length = right - left
            d = s[left]
            left += 1
            if d in need:
                if window[d] == need[d]:
                    valid -= 1
                window[d] -= 1
                
    return s[start:start+length] if length != float('inf') else ""
总结

扩张法和全局滑动窗口技术是非常强大的算法,它们可以在最优时间内解决一些经典问题。在处理字符串和数组时,程序员应该熟练掌握这些技术,并在需要时灵活应用它们。