s = input() n = len(s) # 建立一个字典存储各个元素在窗口中出现的次数 d = defaultdict(int) ans = 0 # 确定窗口左端 left = 0 for right inrange(n): # 如果发现窗口中已经有s[right],将left右移直到窗口中不存在s[right] while d[s[right]] > 0: # 更新字典 d[s[left]] -= 1 left += 1 ans = max(ans, right-left+1)
print(ans)
二、模拟优先队列求区间最值
滑动窗口研究区间的性质,可以用于模拟优先队列从而高效求出区间内的最大值和最小值
例题 1: 附近最小(蓝桥杯第14届省模拟赛) 问题描述:
小蓝有一个序列 a[1],a[2],...,a[n]。给定一个正整数 k,请问对于每一个 1 到 n 之间的正整数i,a[i−k],a[i−k+1],...,a[i+k] 这 2k+1 个数中的最小值是多少?
当某个下标超过 1 到 n 的范围时,数不存在,求最小值时只取存在的那些值。
输入格式:
输入的第一行包含一整数 n,第二行包含 n 个整数,分别表示 a[1],a[2],...,a[n]。第三行包含一个整数 k
# 滑动窗口 + 优先队列 n = int(input()) a = [int(i) for i ininput().split()] k = int(input()) # 在数组右边补k个一定不是最小值的数以免分类讨论 a = a + [a[n-1]+1]*k d = k*2+1# 窗口宽度 ans = [] q = [] # 递增的优先队列 # 注意i是滑动窗口的右端点 for i inrange(n+k): # 如果队列不为空,将所有大于当前元素的队尾元素出队 while q and a[q[-1]] > a[i]: q.pop() # 将新元素的下标入队 q.append(i) # 检查队头元素是否在新区间范围内 if i - q[0] > d-1: q.pop(0) # 将队头元素记录下来 if i >= k: ans.append(a[q[0]])
# 利用滑动窗口模拟优先队列,从而将搜索每一个区间中最值的时间复杂度从O(n*n)优化为O(n) MOD = 998244353 defget_max(nums,step): # the variable called step store the size of interval q = [] max_list = [] for i inrange(len(nums)): while q and nums[q[-1]] < nums[i]: # when the end element of prior-quee is small than the new element # pop out the end element q.pop(-1) # the list store the index of every number because it is more convenient to find # out whether the index is out of the interval or not q.append(i) # when the first element is out of the range of interval, pop it out if q[0] <= i-step: q.pop(0) # when the queue has been built, add the first element into the answer list if i >= step-1: max_list.append(nums[q[0]]) return max_list # using the same theory,we can find out the minist number defget_min(nums,step): q = [] min_list = [] for i inrange(len(nums)): while q and nums[q[-1]] > nums[i]: q.pop(-1) q.append(i) if q[0] <= i-step: q.pop(0) if i >= step-1: min_list.append(nums[q[0]]) return min_list # similarly,we can calculate out the sum of all the numbers in the interval defget_sum(nums,step): sum_list = [] temp = 0 # the pointer called i is actually the right pointer # the left pointer's value is i-step+1 for i inrange(len(nums)): if i < step - 1: temp += nums[i] elif i == step-1: temp += nums[i] sum_list.append(temp) else: temp -= nums[i-step] temp += nums[i] sum_list.append(temp) return sum_list
# the main part of the algorithm # firstly,use the function to find out all the line's extremum n,m,a,b = map(int,input().split()) matrix = [] for i inrange(n): matrix.append([int(j) for j ininput().split()]) # zip the row m_max_one = [] m_min_one = [] for i inrange(n): m_max_one.append(get_max(matrix[i], b)) m_min_one.append(get_min(matrix[i], b)) # transpose the temporary matrix and zip again # the result is the collection of extremum matrix m_max_two = [[0]*n for i inrange(len(m_max_one[0]))] m_min_two = [[0]*n for i inrange(len(m_min_one[0]))] for i inrange(len(m_max_one[0])): for j inrange(len(m_max_one)): m_max_two[i][j] = m_max_one[j][i] m_min_two[i][j] = m_min_one[j][i] # zip the col m_max = [] m_min = [] for i inrange(len(m_max_two)): m_max.append(get_max(m_max_two[i], a)) m_min.append(get_min(m_min_two[i], a)) # calculate the sum of all the sub_matrixs' value res = 0 for i inrange(len(m_max)): for j inrange(len(m_max[0])): res += m_max[i][j]*m_min[i][j] res %= MOD print(res)