滑动窗口(尺取法)

2024-03-24 15:52
文章标签 窗口 滑动 取法

本文主要是介绍滑动窗口(尺取法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

滑动窗口(尺取法)

算法含义:

在解决关于区间特性的题目时保存搜索区间左右端点,然后根据实际要求不断更新左右端点位置的算法

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)

在历年真题中,滑动窗口主要有求追偿不重复子串和模拟优先队列求区间最值两个作用

一、求最长不重复字串

不重复子串:字符串的字串中不包含重复字符的字串

from collections import defaultdicts = input()
n = len(s)
# 建立一个字典存储各个元素在窗口中出现的次数
d = defaultdict(int)
ans = 0
# 确定窗口左端
left = 0
for right in range(n):# 如果发现窗口中已经有s[right],将left右移直到窗口中不存在s[right]while d[s[right]] > 0:# 更新字典d[s[left]] -= 1left += 1ans = max(ans, right-left+1)print(ans)

二、模拟优先队列求区间最值

滑动窗口研究区间的性质,可以用于模拟优先队列从而高效求出区间内的最大值和最小值

例题: 子矩阵
问题描述:

给定一个n x m(n行m列)的矩阵。设一个矩阵的价值为其所有数中的最大值和最小值的乘积。求给定矩阵的所有大小为 a x b (a行b列)的子矩阵的价值的和。答案可能很大,你只需要输出答案对 998244353 取模后的结果。

输入格式:

输入的第一行包含四个整数分别表示n,m,a,b,相邻整数之间使用一个空格分隔。接下来
n行每行包含m个整数,相邻整数之间使用一个空格分隔,表示矩阵中的每个数 A i j A_{ij} Aij

输出格式

输出一行包含一个整数表示答案。

# 利用滑动窗口模拟优先队列,从而将搜索每一个区间中最值的时间复杂度从O(n*n)优化为O(n)
MOD = 998244353
def get_max(nums,step):# the variable called step store the size of intervalq = []max_list = []for i in range(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 elementq.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 outif q[0] <= i-step:q.pop(0)# when the queue has been built, add the first element into the answer listif i >= step-1:max_list.append(nums[q[0]])return max_list
# using the same theory,we can find out the minist number
def get_min(nums,step):q = []min_list = []for i in range(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
def get_sum(nums,step):sum_list = []temp = 0# the pointer called i is actually the right pointer# the left pointer's value is i-step+1for i in range(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 in range(n):matrix.append([int(j) for j in input().split()])
# zip the row
m_max_one = []
m_min_one = []
for i in range(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 in range(len(m_max_one[0]))]
m_min_two = [[0]*n for i in range(len(m_min_one[0]))]
for i in range(len(m_max_one[0])):for j in range(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 in range(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 in range(len(m_max)):for j in range(len(m_max[0])):res += m_max[i][j]*m_min[i][j]res %= MOD
print(res)

这篇关于滑动窗口(尺取法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/842064

相关文章

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

主窗口的设计与开发(二)

主窗口的设计与开发(二) 前言         在上一集当中,我们完成了主窗口的初始化,主窗口包括了左中右三个区域。我们还完成了对左窗口的初始化,左窗口包括了用户头像、会话标签页按钮、好友标签页按钮以及好友申请标签页按钮。对于切换每个标签页,我们还做了初始化信号槽的内容。最后我们将整个MainWidget类设置为单例模式。         那么这一集我们将继续完成主窗口的设计与开发,这一集我

QtC++截图支持窗口获取

介绍 在截图工具中你会发现,接触到窗口后会自动圈出目标窗口,个别强大一点的还能进行元素识别可以自动圈出元素,那么今天简单分析一下QTc++如何获取窗口并圈出当前鼠标下的窗口。 介绍1.如何获取所有窗口2.比较函数3.实现窗口判断 结尾 1.如何获取所有窗口 1.我们需要调用windows接口EnumWindowsProc回调函数来获取所有顶级窗口,需要包含windows.

运行.bat文件,如何在Dos窗口里面得到该文件的路径

把java代码打包成.jar文件,编写一个.bat文件,执行该文件,编译.jar包;(.bat,.jar放在同一个文件夹下) 运行.bat文件,如何在Dos窗口里面得到该文件的路径,并运行.jar文件: echo 当前盘符:%~d0 echo 当前路径:%cd% echo 当前执行命令行:%0 echo 当前bat文件路径:%~dp0 echo 当前bat文件短路径:%~sdp0 nc

类codepen的实现可拖拽窗口demo

首先说下思想 flex或者其他布局方式,实现左右分割布局,主盒子宽度100%,左右布局中包含一个分割条(可在布局容器中,也可以单独定义)为分隔条绑定鼠标点击事件,为document绑定鼠标移动事件和鼠标放开事件,通过监听鼠标移动事件和上一个状态保存下来的鼠标位置作对比,判断当前鼠标移动方向(往左还是往右)然后计算当前鼠标位置和鼠标点击位置的距离,来计算左右容器的变化,然后通过dom的方式设置宽度

【leetcode详解】考试的最大困扰度(滑动窗口典例)

实战总结: sum += answerKey[right] == c; 经典操作,将判断语句转化为0, 1接收来计数//大问题分解: 对'T'还是'F'做修改, 传参为c//滑动窗口: 遍历, 维护left& right指向 及 c的个数, 更新不知从何下手写代码时:考虑先写好第一次的,然后以此为基础补充代码以适后续情况 题面: 解题感受: 思路总体好想, 实现略有挑战。 思路分析:

【每日一题】LeetCode 2379.得到K个黑块的最少涂色次数(字符串、滑动窗口)

【每日一题】LeetCode 2379.得到K个黑块的最少涂色次数(字符串、滑动窗口) 题目描述 给定一个字符串 blocks,其中每个字符代表一个颜色块,可以是 ‘W’(白色)或 ‘B’(黑色)。你需要找到一个至少包含 k 个连续黑色块的子串。每次操作可以将一个白色块变成黑色块。你的任务是找到至少出现一次连续 k 个黑色块的最少操作次数。 和该题目类似:【每日一题】LeetCode 202

【视频教程】手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06)

现在的新版AppWizard已经比较好用,用户可以轻松的创建各种项目常规界面。 比如早期创建一个支持滑动的主界面框架,并且可以跳转各种子界面,仅仅界面布局和各种图片格式转换都要花不少时间,而现在使用AppWizard,可以说轻轻松松,毫不费力。 用户唯一要做的就是根据自己的芯片性能做一定的速度优化。 视频: https://www.bilibili.com/video/BV17Rp3eLE