当前位置: 首页 > news >正文

智能建站模板徐州注册公司

智能建站模板,徐州注册公司,自己动手制作网站,西安微网站滑动窗口介绍 滑动窗口是一种我们想象中的数据结构 它是用来解决算法问题的 我们可以想象出一个数组 然后再在这个数组的起始位置想象出两个指针 L 和 R 我们对于这两个指针做出以下规定 L 和 R指针只能往右移动L指针不能走到R指针的右边我们只能看到L指针和R指针中间的数字 …

滑动窗口介绍

滑动窗口是一种我们想象中的数据结构 它是用来解决算法问题的

在这里插入图片描述

我们可以想象出一个数组 然后再在这个数组的起始位置想象出两个指针 L 和 R

在这里插入图片描述

我们对于这两个指针做出以下规定

  • L 和 R指针只能往右移动
  • L指针不能走到R指针的右边
  • 我们只能看到L指针和R指针中间的数字

比如说当前L和R指针重合 我们就什么数字都看不见

如果此时R指针往右走一步 那么我们就能看到L指针和R指针中间的数组的数字

又因为这种移动的方式特别像滑动 所以说我们将这种想象出来的数据结构叫做滑动窗口

如何确定一个滑动窗口内的最大值

如果我们每次都遍历去获取滑动窗口的最大值的话那么每次获取的时间复杂度就是O(N)了 这样子明显很复杂 所以说我们需要想想别的方式去找到最大值

这里直接给出结论:

  • 我们使用双端队列去获取一个滑动窗口内的最大值
  • 双端队列的意义是 : 此时开始缩小滑动窗口 哪些数字可能成为最大值

为了让双端队列能够实现它的意义 我们做出以下规定

  • 让R指针向右滑动的时候 我们从右边插入数字的下标到双端队列中
  • 如果说插入的数字要大于原来的数字 我们让原来的数字出队列
  • 让L指针向右滑动的时候 我们从左边开始比较双端队列第一个(左边数起)下标和L指针的下标
  • 如果说L指针的下标要大于双端队列最左边的下标 则将其弹出

至于C++中的双端队列 大家可以参考这篇博客 双端队列

窗口内最大值

假设一个固定大小为W的窗口 依次划过数组arr

让你依次返回每次窗口移动时窗口中的最大值

假设数组arr为 【4 , 3 , 5 ,4, 3, 3, 6, 7】 W = 3

返回【5 , 5, 5, 4, 6, 7】


这道题目实际上就是一个滑动窗口最大值的简单版本

我们使用一个双端队列就能很轻松的实现

面对这个问题我们可以拆分成两部分来解决

  1. 首先把滑动窗口的大小扩大到3
  2. 接着滑动窗口整体开始移动

两部分的代码都不算难 代码表示如下

void process5(vector<int>& arr , vector<int>& ans , int W)
{deque<int> dq(0  , 0);for (int R = 0; R < W; R++){while (!dq.empty() && arr[dq.front()] <= arr[R]){dq.pop_back();}    dq.push_back(R);    }    
  int R = W - 1;    int L = 0;    int N = static_cast<int>(arr.size());    while (R < N)    {    while (!dq.empty() && arr[dq.back()] <= arr[R])                                                                                                                          { dq.pop_back();}                     dq.push_back(R);while (L > dq.front())    {                         dq.pop_front();}                     ans.push_back(arr[dq.front()]);L++;    R++;}
}

这道题目给我们的提醒主要有两个

  1. 当我们R指针右移的时候要使用while来进行判断
  2. R指针在初始化之后要重置 否则会出现一些错误 为了避免这些错误 我们最好每次使用一个变量之前对其进行初始化

子数组中符合条件的个数

给定一个整形数组arr 和一个整数num

某个arr中的子数组sub 必须要满足

sub中的最大值减去sub中的最小值小于等于num

返回sub中达标的子数组的数量


我们首先分析下问题

如果我们没有学过滑动窗口和双端队列 那么这道题我们会使用暴力的方式来得到答案

三个for循环嵌套 时间复杂度就变成了n的三次方 这显然是不可以的

当我们使用滑动窗口解决这个问题的时候 由于我们的左右两个下标都是单向的往右边移动 所以说此时的时间复杂度就是N


当我们得到两个下标满足上述条件时 比如说0 ~ N上的最大值减去0~N中的最小值小于等于num

此时我们就可以说 左下标为0 右下标为0 ~ N-1上的任意一个子数组都满足条件

因为此时最大值只有可能变小 最小值只有可能变大 所以说它们之间的差值肯定还是会小于等于num

所以我们就能确定 以0为左边界 N为右边界上符合条件的子数组有 N - 0 + 1个

之后我们左边界右移即可


整体思路如下

  • 我们使用两个双端队列来记录子数组的最大值和最小值
  • 我们让右边界一直右移动 直到子数组不满足条件为止
  • 此时通过上面的技巧计算出左边界到右边界-1的满足条件子数组个数 之后左边界++

代码表示如下

int process(vector<int>& arr, int num)
{deque<int> Max_Win(0, 0);deque<int> Min_Win(0, 0);int count = 0;int R = 0;int N = static_cast<int>(arr.size());for (int L = 0; L < N; L++){while (R < N){while (!Max_Win.empty() && arr[Max_Win.back()] <= arr[R]){Max_Win.pop_back();}Max_Win.push_back(R);while (!Min_Win.empty() && arr[Min_Win.back()] >= arr[R]){Min_Win.pop_back();}Min_Win.push_back(R);if (arr[Max_Win.front()] - arr[Min_Win.front()] > num){break;}else{R++;}}count += R - L;if (Max_Win.front() == L){Max_Win.pop_front();}if (Min_Win.front() == L){Min_Win.pop_front();}}return count;
}

这里有一点需要注意的是

 count += R - L;

语句必须要放到while循环的外面才行 否则会因为R下标越界的问题而导致不会执行if语句 最终导致count计算不完整

http://www.yayakq.cn/news/197958/

相关文章:

  • 江西省住房与城乡建设厅网站深圳市网络营销推广平台
  • 张家口网站建设vewan银行门户网站建设ppt
  • 网站开发应该学哪门语言影视公司排行榜
  • 地税城市维护建设税网站是什么app是什么意思怎么用
  • 微信做的团购网站深圳南山住房和建设局网站
  • 在线视频网站 一级做爰片wordpress邀请奖励
  • 柳州网站seo北京网络建站
  • 百度网址大全手机版整站优化关键词推广
  • asp.net 网站提速深圳软件系统开发
  • 网站建设分组任务热门网站建设加盟平台
  • 建立了网站后如何发贴织梦大气绿色大气农业能源化工机械产品企业网站源码模版
  • 超级搜索引擎丈哥seo博客工具
  • 中文网站后台途牛旅游网站建设方案
  • 歌曲网站模板做积分网站
  • 群晖 做网站服务器软件免费下载的网站大全
  • wordpress 取消重定向新乡网站搜索引擎优化
  • 个人网站如何制作全球搜 建设网站
  • 网站建设服务中心程序ui设计
  • 网站建设的主要结构网站快速过备案
  • 鱼骨建站公司网络推广怎么做效果好
  • 怎么更改网站常州网站建设报价
  • 网站模板哪个网站好长沙 汽车 网站建设
  • 阿里巴巴做网站营销有没有用如何提高网站关键词排名
  • 帝国小说网站模板2020应该建设什么网站
  • 网站ip屏蔽怎么做网页链接跳转
  • 东莞网站推广优化搜索推广网站虚拟主机有什么用
  • 网站做中英文切换怎么做一个手机网站
  • 做团购网站有什么难处微信官网站
  • 网站导航菜单兰虹口基础微网站开发
  • 兰州seo安安网站建设太原网络推广公司哪家好