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

商业空间设计案例ppt/seo推广排名公司

商业空间设计案例ppt,seo推广排名公司,武汉学校网站开发,国外设计有名网站在双指针的技巧中,有一类比较特殊的技巧,通过滑动左右指针来求解问题。 虽然我们上一篇也提到过一些通过left和right移动来求解的问题。 双指针的配合 但滑动窗口这类问题更多的会固定一边滑动另一边,这个更像窗口的大小改变,所…

在双指针的技巧中,有一类比较特殊的技巧,通过滑动左右指针来求解问题。

虽然我们上一篇也提到过一些通过left和right移动来求解的问题。
双指针的配合

但滑动窗口这类问题更多的会固定一边滑动另一边,这个更像窗口的大小改变,所以叫做滑动窗口。

数组滑动

先来看几道数组滑动的题目,感受滑动窗口的较为固定的模式。

leetcode 209 长度最小的子数组

给定一个数组,找到和大于等于target的长度最小的连续子数组。

因为是连续子数组,所以可以用两个指针来滑动。

滑动窗口的核心

用一个例子来了解滑动窗口的核心动作:

比如数组[2,3,1,2,4,3],我们定义left指针和right指针都在起始位置(2),然后right往右走来扩大边界,[2],[2,3],[2,3,1],[2,3,1,2],这个窗口不断扩大。

什么时候停止扩大右边界呢?

当满足题目条件时。

这道题中就是在和大于等于target的时候,我们就可以停止right,开始缩小窗口了。

这时候我们先把[2,3,1,2]这个结果记下来,再寻找下一个结果。

缩小窗口,left开始移动,变成了[3,1,2],发现又不满足条件了,那么left就可以休息了。

right继续工作,再扩大,[3,1,2,4],发现可以满足了,记录下来,然后left继续缩小窗口。

[1,2,4],依旧满足,记录下来,继续缩小。

[2,4],不满足了,left休息right工作,扩大为[2,4,3],记录下来。

left继续缩小,[4,3],也满足,记录下来。

最后在所有记录里面找到最短的即可。

int minSubArrayLen(int target, vector<int>& nums) {int left=0;int right=0; int sum=0; //求和int result=INT32_MAX;//因为要求最短的,所以设定初始为最大while(right<nums.size()){//向右扩大窗口sum+=nums[right];right++;while(sum>=target){//满足条件做记录,然后缩小窗口result=result<(right-left)?result:(right-left);sum-=nums[left];left++;}}return result==INT32_MAX?0:result;}

这是滑动窗口一种比较经典的模板。要注意如果right++写在while循环的最后,那么长度就应该是right-left+1

当然这个长度具体是多少要看我们需要的数组包不包括right这一位,也就是左闭右开和左闭右闭的区别。

巩固练习

还有一道滑动窗口的题目

leetocde 904 水果成篮

这道题可以翻译为求只包含两种元素的最长连续子数组。

比如[1,2,3,2,2],答案就是[2,3,2,2]。

我们用滑动窗口来解决这个问题,在遇到第三种元素时就记录前面这个子数组的长度,然后再重新选择两种元素,继续扩大窗口。

先看代码:

int totalFruit(vector<int>& fruits) {int left=0,right=0;int f1=fruits[left],f2=fruits[right];int maxLength=0;while(right<fruits.size()){if(fruits[right]!=f1&&fruits[right]!=f2){//遇到第三种元素maxLength=maxLength>(right-left)?maxLength:(right-left);left=right-1;f1=fruits[left];f2=fruits[right];while(left>=1&&fruits[left-1]==f1){left--;}}right++;}return maxLength>(right-left)?maxLength:(right-left);

首先设定两种元素为fruits[left]和fruits[right],如果遇到第三种元素,就记录长度。

这里最核心的做法是让 left=right-1,即left指向right的前一位。这样可以快速定位两种元素的位置。

如果left前面还有与它相等的元素,那么再让left–去将它们包含进来。

我们用例子来快速理解一下:比如[3,3,3,1,1,2,2,1,1,2]

  • 首先fruits[left]和fruits[right]都是3,所以在遇到1的时候就要记录长度,并且移动left。

  • 这时候才是真正定义两种元素的开始,f1是3,f2是1。并且left回退到了起始位置,包含了所有的3。

  • 当遇到2时,记录前面序列[3,3,3,1,1]的长度,然后left指向[3,3,3,1,1]的最后一个1,同时回退去包含前面一个1

  • 一直移动到结尾,序列就变为[1,1,2,2,1,1,2]

需要注意:

  • 为什么right++在记录长度之后,长度却还是right-left?这就和上题所说的一样,当我们遇到第三种元素时,right已经不在这个序列中了,相当于左闭右开,所以不需要+1
  • 最后为什么不是直接返回maxLength?因为right最后可能会退出循环,但并未保存最后一次的结果。例子中就是这样的。

字符串滑动

最小覆盖子串

滑动窗口最经典的一道hard题目,就是最小覆盖子串

leetcode 76 最小覆盖子串

是要在给定的子串s中寻找包含t的最短子串。

比如s=ADOBECODEBANC,t=ABC,那么最短的就是BANC

其实这道题本质上还是左右边界的移动。我们可以根据这个例子简单理解这个过程:

  • 首先left和right都指向左边,然后right开始移动。
  • 移动到什么时候停止呢?**在这个窗口包含所有t的字符时。**这时就可以记录长度了。
  • left开始移动,left什么时候停止呢?在不包含t的所有字符时(这里容易产生歧义,比如t是ABC,那么在不包含任意一个的时候left就会停止),然后继续移动right
  • 这种模式和我们开篇说的“left在满足条件时移动,不满足时停止”是一致的。
  • 最后取最短的即可。

代码看上去很长,但非常有规律。

string minWindow(string s, string t) {int left=0;//左指针int right=0;//右指针//需要最小长度和起点,才能调用substr取子串int minLength=INT32_MAX;//int start=0;//当一个字符匹配成功且数量达到needs的要求就让match+1int match=0;unordered_map<char,int>window;unordered_map<char,int>needs;for(char c:t)//初始化needsneeds[c]++;while(right<s.size()){char c1=s[right];if(needs.count(c1)){//如果needs中有c1,那么就让window对应+1window[c1]++;if(window[c1]==needs[c1])//当一个字符完全匹配后,match+1match++;}right++;while(match==needs.size()){//当字符都匹配后,right停止,开始动left缩小窗口if (right - left < minLength) {//取较小的值start = left;minLength = right - left;}char c2=s[left];if(needs.count(c2)){//如果needs中有c2,那么window将c2移出。当不满足条件时,left就不动了。开始动right。window[c2]--;if(window[c2]<needs[c2]){match--;}  }left++;} }return minLength==INT32_MAX?"":s.substr(start,minLength);//取最小子串}

我们需要维护两个unordered_map,一个是用来记录t中字符的needs,另一个是用来匹配的window。

window虽说是窗口,但是实际使用的时候我们只去匹配t中有的字符,其余字符就直接忽略,让right++就好。

windows的匹配过程是分为两层的:

  • 第一层是遇到字符就记录下来,但是t中有可能有重复字符,所以需要多次记录
  • 如果某一个字符的数量符合needs中要求的数量,那么这个字符就匹配成功,对应的match就加1
  • 直到match符合needs的长度时,才包含了所有的字符。

这种解法很巧妙,建议全文理解。

找到字符串中所有字母异位词

leetocde 438 找到字符串中所有字母异位词

这道题给字母的排列取了一个高端的名字,字母异位词。

输入: s = “cbaebabacd”, p = “abc”
输出: [0,6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。

其实就是在s中找到p的排列,然后返回他们的起始下标。

继续使用滑动窗口:

vector<int> findAnagrams(string s, string p) {int left=0;int right=0;int match=0;vector<int>res;unordered_map<char,int>window;unordered_map<char,int>needs;for(char c:p)needs[c]++;while(right<s.size()){char c1=s[right];if(needs.count(c1)){window[c1]++;if(window[c1]==needs[c1]){match++;}}right++;while(match==needs.size()){if((right-left)==p.size())//只有这里有区别,条件的区别。res.push_back(left);char c2=s[left];left++;if(needs.count(c2)){window[c2]--;if(window[c2]<needs[c2]){match--;}}}}return res;}

因为和上题中的解法一致,所以就不写注释了,如果明白上题那么这道题就很简单了。

字符串的排列

leetcode 567 字符串的排列

如果s1的排列之一是s2的子串,那么返回true

和上一题也是比较相似的。甚至更简单。只要有一个排列就可以返回true了

继续滑动:

 bool checkInclusion(string s1, string s2) {int left=0;int right=0;int match=0;unordered_map<char,int>window;unordered_map<char,int>needs;for(char c:s1)needs[c]++;while(right<s2.size()){char c1=s2[right];if(needs.count(c1)){window[c1]++;if(window[c1]==needs[c1]){match++;}}right++;while(match==needs.size()){if(right-left==s1.size()){//长度符合直接返回return true;}char c2=s2[left];if(needs.count(c2)){window[c2]--;if(window[c2]<needs[c2]){match--;}  }left++;}}return false;}

还是一致的,只是到达条件处的一点点区别。

http://www.jmfq.cn/news/5225977.html

相关文章:

  • 机票网站建设/网站设计案例
  • js 网站怎么做中英文/关键词挖掘工具
  • 苏州网站建设 凡仕臣网络/微信推广图片
  • 网站描述优化/推广优化排名
  • wordpress 首页 修改/seo职业规划
  • 炫酷网站模板免费下载/营销策略ppt
  • 为女朋友做的网站/百度帐号管家
  • 大淘客网站推广位怎么做/西安百度推广代理商
  • 网站右侧固定标题怎么做/浏览器大全
  • 用织梦做网站能练技术吗/网络事件营销案例
  • 抖音代运营怎么解绑/seo搜索引擎优化培训班
  • 怎么建自己的手机网站吗/北京知名seo公司精准互联
  • 装饰工程验收规范最新版/网站seo收录
  • jsp做网站毕业设计/网络推广费用
  • 100个最好的微信小程序/免费的seo网站
  • 小县城 交友网站 很难做/域名查询注册商
  • 网站建设合同的主要内容/google关键词排名
  • 一键建设网站/成都官网seo服务
  • 学做网站论坛坑人吗/建站开发
  • 怎么创建子网站/成全高清免费观看mv
  • 本地网站建设流程/深圳推广公司哪家好
  • 网站备案号中信息有变/上海有名网站建站开发公司
  • 做ppt常用的网站有哪些/唐山seo推广公司
  • 怎么评价网站做的好坏/中国去中心化搜索引擎
  • 生意街创业商机网/seo推广平台服务
  • 建网站电脑版和手机版怎么做/青岛官网seo公司
  • 湖南智能网站建设推荐/网络黄页推广软件哪个好用
  • 网站建设怎么选公司/今天重大新闻事件
  • 网站导航栏设计代码/百度搜索引擎优化怎么做
  • 完善运营网站建设/今日热搜榜排名最新