python窗口滑动算法_滑动 窗口-leetcode-java/python代码

注意:计算窗口内数据的时机很重要,是在while前还是while后要

class Solution:

def minWindow(self, s: str, t: str) -> str:

needs = dict() # 需要的子串

for t_char in t:

if needs.get(t_char):

needs[t_char] = needs[t_char] + 1

else:

needs[t_char] = 1

window = dict() # 滑动的窗口

for t_char in t: #默认窗口中的元素都为0

window[t_char] = 0

left, right, valid = 0, 0, 0

min_repeat = s + "A"

while right < len(s):

right_cur = s[right] #窗口向右滑动,扩大

right += 1

if window.get(right_cur) != None:

window[right_cur] = window[right_cur] + 1 # 符合要求把内容放入窗口

if window[right_cur] == needs[right_cur]:

valid += 1

while valid == len(needs) and left < len(s):

if len(s[left:right]) < len(min_repeat):

min_repeat = s[left:right] # 存储满足要求的最小的子串

left_cur = s[left]

if window.get(left_cur) != None:

window[left_cur] = window[left_cur] - 1 # 缩小窗口

if window[left_cur] < needs[left_cur]:

valid -= 1

left += 1

if min_repeat == s + "A": return ''

return min_repeat

class Solution:

def maxSlidingWindow(self, nums,k):

if k > len(nums):

return [max(nums)]

# if k==1:return nums

left = 0

right = k

max_result = []

max_val = max(nums[left:right])

max_index = nums[left:right].index(max_val)

max_result.append(max_val)

left += 1

right += 1

while right <= len(nums): # 不要每一个窗口都重新计算最大值,利用每次只移动一个元素,因此比较新的元素和最大值之间谁大即可。

if max_index == left-1:#考虑最大值在最左边界的特殊情况

if nums[right-1]>=max_val:

max_index = right-1

max_val = nums[right-1]

else:

max_val = max(nums[left:right])

max_index = left+nums[left:right].index(max_val)

else:

if nums[right-1] >=max_val:

max_index = right-1

max_val = nums[right-1]

max_result.append(max_val)

left+=1

right+=1

return max_result

class Solution:

def characterReplacement(self, s: str, k: int) -> int:

# 何时替换:在字母种类尽可能的少,分布密集的地方替换k次

'''替换算法:一:除去窗口内出现最多的字母,窗口内其余不同的字母出现次数之和小于等于k时,可能最大记录下来;

然后继续扩大窗口,直到大于k时缩小窗口,缩小窗口时继续执行一步骤'''

# 则该窗口内的元素为最多

# 除去最大值之后,其余值之和为k

iter_dict = {chr(65 + i): 0 for i in range(26)}

left = 0

right = 0

lenght = 0

while right < len(s):

right_cur = s[right]

right += 1

iter_dict[right_cur] = iter_dict[right_cur] + 1

max_value = max(iter_dict.values())

total_sum = sum(iter_dict.values()) - max_value

if total_sum <= k or total_sum ==0:

lenght = max(lenght, right - left)

elif total_sum > k and left < len(s): # 缩小窗口

left_cur = s[left]

left+=1

iter_dict[left_cur] = iter_dict[left_cur] - 1

max_value = max(iter_dict.values())

total_sum = sum(iter_dict.values()) - max_value

if total_sum <= k or total_sum==0:

lenght = max(lenght, right - left)

return lenght

print(Solution().characterReplacement("AABABBA",1))

class Solution:

def equalSubstring(self, s, t, maxCost):

left = 0

right = 0

consume = 0

length = 0

while right < len(s):

# 扩大窗口

right_temp = abs(ord(s[right]) - ord(t[right]))

consume += right_temp

if consume <= maxCost:

length = max(length, right - left + 1)

right += 1

if consume > maxCost:

# 缩小窗口

left_temp = abs(ord(s[left]) - ord(t[left]))

consume -= left_temp

left += 1

return length

class Solution:

def longestOnes(self, A, K):

length, left, right, count = 0, 0, 0, 0

while right < len(A):

right_cur = A[right]

right += 1

if right_cur == 0:

count += 1

while count > K and left < len(A):

left_cur = A[left]

left += 1

if left_cur == 0:

count -= 1

#窗口内0的个数小于等于k时,也就是可以该窗口内的0都可以替换,length

length =max(length,right-left)

return length

class Solution:

def maxTurbulenceSize(self, A):

if len(A) == 1: return 1

if len(A) == 0: return 0

symbol = []

for i in range(len(A) - 1):

if A[i] - A[i + 1] > 0:

symbol.append('>')

elif A[i] - A[i + 1] < 0:

symbol.append('<')

else:

symbol.append('=')

if len(symbol) == 0 and len(A) > 1: return 1

left, right, length = 0, 0, 0

result = ''

while right < len(symbol):

right_cur = symbol[right]

result = result + right_cur

right += 1

while len(result)>0 and result[-1] == '=' or len(result) >1 and result[-1] == result[-2]:

# left_cur = symbol[left]

left +=1

result = result[1:]

length = max(length,len(result)+1)

return length

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值