滑动窗口经典题目Sliding windows

文章目录

    • 简介
    • 340 Longest Substring with K Distinct Characters (medium)
      • 代码
    • Smallest Subarray with a given sum (easy)
      • 代码
    • 325 Maximum Size Subarray Sum Equals k
      • 代码
    • 904 Fruits into Baskets (medium)
    • 003 No-repeat Substring (hard)
      • 代码
    • Longest Substring with Same Letters after Replacement (hard)

简介

这里记录一下使用python写的滑动窗口经典题的题解,欢迎大家指正和交流。

340 Longest Substring with K Distinct Characters (medium)

含有不同的k个字符的最长子串

  • bitmap[]存储每个字符出现次数,
  • left right左右指针
  • count 统计当前不同字符的个数
  • res 当前最长子串长度

包含k个字符以上左边界右移

有边界右移,如果出现新的字符则count++

如果count <= k, 更新res

代码

def longestSubstringKDistinctLetter(nums, k):
    bitmap = dict()
    left, right = 0, 0
    count = 0
    res = 0
    for i in range(256):
        bitmap[chr(i)] = 0
    while(right < len(nums)):
        if(count > k):
            if(bitmap[nums[left]] - 1 == 0):
                count -= 1
            bitmap[nums[left]] -= 1
            left += 1
            continue
            # 为什么要加continue,因为
            # 进入这个if的就是因为此时count>k,left必须左移到count = k,continue的意义是
            # 跳过后面的right的右移
        
        if(bitmap[nums[right]] == 0):
            count += 1
        bitmap[nums[right]] = bitmap[nums[right]] + 1
            
        
        if(count <= k): res = max(res, right - left + 1)
        right += 1
    return res
        

Smallest Subarray with a given sum (easy)

  • 设置start end, 初始化最小长度lenn为INF
  1. end后移,增加sum,如果sum>value

  2. while (sum - nums[start] >= k): start后移,更新lenn,返回2

    如果sum - nums[start] < k: 返回1

代码

def smallestSubarray(nums, value):
    start, end = 0, 0
    if(len(nums) == 0): return 0
    lenn = float('inf')
    summ = 0
    while(end < len(nums)):
        summ += nums[end]
        while(summ > value):
            if(summ - nums[start] > value):
                start += 1
                summ = summ - nums[start]
                lenn = min(lenn, end - start + 1)
        end += 1
    return lenn

325 Maximum Size Subarray Sum Equals k

  1. map结构存储前n个数的n个和
  2. 如果当前k和sum存在差值,是否存在sum
  • 如果存在:得到max_count = max(max_count, i + 1 - map(map[sum - k]))
  • 如果不存在sum: map[sum] = i+1

代码

def maxSizeOfSubarr(arr, k):
    if(len(arr)==0): return 0
    sum1=0
    res=0
    hasht = dict()
    hasht[0] = 0
    for i in range(0, len(arr)):
        sum1 += arr[i]
        if((sum1 - k) in hasht):
            res = max(res, i + 1 - hasht[sum1-k])
        if(sum1 not in hasht):
            hasht[sum1] = i + 1
    return res

904 Fruits into Baskets (medium)

从任意位置开始,如果最多只能收集两种水果,
那么最多可以收集多少水果,我看着不方便,我理解为最多可以收集到几颗果树
感觉和340是一样的
具体思路参考340

def maximumFruits(nums, k=2):
    bitmap = dict()
    left, right = 0, 0
    count = 0
    res = 0
    for i in range(256):
        bitmap[i] = 0
    while(right < len(nums)):
        if(count > k):
            if(bitmap[nums[left]] - 1 == 0):
                count -= 1
            bitmap[nums[left]] -= 1
            left += 1
            continue
            # 为什么要加continue,因为
            # 进入这个if的就是因为此时count>k,left必须左移到count = k,continue的意义是
            # 跳过后面的right的右移
        if(bitmap[nums[right]] == 0):
            count += 1
        bitmap[nums[right]] = bitmap[nums[right]] + 1
            
        
        if(count <= k): res = max(res, right - left + 1)
        right += 1
    return res

003 No-repeat Substring (hard)

求最长无重复子串, 给出一个字符串, 从所有子串中, 找出最长, 且没有重复字母的子串的长度.

  • 解法:
    利用set存储所有出现过的字符,res记录最长子串的长度
    right右移,while(right 检查s[right]已经出现在set中
    如果没有出现:更新res和set
    否则:
    然后left右移,直到s[left] == s[right] set.remove(s[left]) left++

代码

def findLongestSubstr(s):
    right, left, res = 0, 0, 0
    length = len(s)
    sett = set()
    while(right < length):
        if(s[right] not in sett):
            res = max(res,  right - left + 1)
            sett.add(s[right])
            right += 1
        else:
            while(s[left] != s[right]):
                left += 1
            sett.remove(s[left])
            left += 1
    return res

Longest Substring with Same Letters after Replacement (hard)

替换后最长重复子串

双指针窗口滑动法。使用两个指针分别作为窗口的left、right,
不断右移动right指针(扩大窗口),
将窗口中的字符数作为一个中间结果(替换后的最长重复字符),
当窗口大小 - 窗口中出现次数最多的字符数即是需要替换的字母数。
如果需要替换的字母数超过了k,则说明需要缩小窗口(右移left)。

def maxLengthRepeatedSubstr(strr, k):
    right, left = 0, 0
    lenn = len(strr)
    letter_map = dict()
    count, res = 0, 0
    for i in range(26):
        letter_map[chr(ord('A') + i)] = 0
    
    while(right < lenn):
        letter_map[strr[right]] += 1
        count = max(count, letter_map[strr[right]])
        while(right - left + 1 - count > k):
            letter_map[strr[left]] -= 1
            left += 1
        
        res = max(res, right - left + 1)
        right += 1
    return res

大家共勉~

你可能感兴趣的:(算法,算法,leetcode,python)