双指针和滑动窗口
双指针
双指针其实跟滑动窗口类似。它利用遍历数组的某种单调性,使得运行的时间复杂度可以从 O(n ^ 2) 降到 O(n)。
def double_pointer(nums: List[int], target: int):    n = len(nums)    buf = {}    l = 0    res = []
    for r, x in enumerate(nums):        while x in buf:            buf.pop(nums[l])            l += 1        buf[x] = r        if x == target:            res.append(l)    return res滑动窗口
一般对于任何题目,都有这样一个模板
def sliding_window(nums: List[int], k: int):    # 这里的输入k也可以是别的什么条件,反正滑动窗口的题目,就是要保证窗口内的元素满足某种条件    n = len(nums)    i = 0 # 窗口左边界    s = 0 # 窗口内元素的某个条件    res = inf # 结果是最长超过k的子数组的长度    # 窗口右边界 x = nums[j]    for j, x in enumerate(nums):        s += x # 更新窗口内元素        while <窗口内元素符合条件>:            res =  # 更新结果            s -= nums[i] # 窗口左边界右移,直到窗口内元素不满足条件            i += 1    return res if res != inf else -1对于需要hash的题目,如果你坚持用dict()或者{}做,那么你可以这样初始化
d = {} # d = dict()for c in s:    d[c] = d.get(c, 0) + 1或者你可以用defaultdict()或者collections.Counter(),这样就不需要考虑初始化的问题
buf = defaultdict(int)buf = Counter(s)