一:Minimum Size Subarray Sum(最小长度子数组的和O(N))

题目:

Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.

分析:一開始我採用的是LIS(longest increased sequence)中的最长递增子序列中的动态规划的思想。能通过,可是时间复杂度为O(N

^2);。;另外一种方法是採用双指针+滑动窗体的思想。时间复杂度为O(N)。 严格意义上说是2N。,比方 [1,2,3,15,3,4,5,15] s=14,,,仅仅有在15处将前面的元素又又一次加了一遍,故为2N

初始快慢指针都为0,fast指针向前移动。当slow和fast中连续字数组的和大于s时。我们就開始缩减窗体,不断的对slow进行向前移动直到sum小于s,然后再移动fast继续循环

代码:

class Solution {
public:// 法一/*int minSubArrayLen(int s, vector<int>& nums) {int result = nums.size();bool flag = false;for(int i = 0; i < nums.size(); i++){if(nums[i] >= s) return 1;int sum = nums[i];for(int j = i-1; j >= 0; j--){sum += nums[j];if(sum >= s){result = min(result, i-j+1);flag = true;break;}}}if(flag)return result;return 0;}*/int minSubArrayLen(int s, vector<int>& nums) {     // 滑动窗体的形式+双指针int result = nums.size()+1;int frontPoint = 0, sum = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i];while(sum >= s){    // 找到了窗体result = min(result, i - frontPoint + 1);   // 窗体是否满足要求sum -= nums[frontPoint++];            // 缩减窗体}}return result == (nums.size()+1) ?

0:result; } };

二:Minimum Window Substring

题目:

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the emtpy string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

分析:这道题刚開始我採用类似于上面滑动窗体的方法,可是每次都要推断当前字符串中是否全然包括字符串t,这个推断就会提升时间复杂度,结果导致TLE。后面參看了discuss中的方法,很巧妙,也放在这里。代码中map用来存放t字符串中的字符及出现的次数,而window用来存放字符串t中每一个字符在字符串s中出现的次数。lettercounts是一个标记变量,当等于t.size()的时候。就表示得到了一个全然包括t的字符子串。然后移动慢指针缩减窗体。

代码:

TLE:

class Solution {
public:bool isContain(const string &sstr, const string &t){for(int i = 0; i < t.size(); i++){if(sstr.find_first_of(t[i]) == string::npos) return false;}return true;}string minWindow(string s, string t) {int result = s.size()+1, frontPoint = 0;string str="";for(int i = 0; i < s.size(); i++){while(isContain(s.substr(frontPoint, i-frontPoint+1) , t)){if(result > i-frontPoint+1){result = i-frontPoint+1;str = s.substr(frontPoint, i-frontPoint+1);}frontPoint++;}}return str;}
};

AC代码:

class Solution {
public:string minWindow(string s, string t) {string result;if(s.size() == 0 || t.size() == 0) return result;unordered_map<char, int> map;unordered_map<char, int> window;  // 滑动窗体int lettercounts = 0;               // 标记变量,当等于t.size()的时候。该窗体就是一个全然包括字符串t的子串int minLen = s.size()+1;for(int i = 0; i < t.size(); i++)  // 将t放入map中。就是为了加速map[t[i]]++;for(int fast = 0, slow = 0; fast < s.size(); fast++){  // 快慢指针,快指针不断向前移动,char c = s[fast];if(map.find(c) != map.end()){      // window[c]++;if(window[c] <= map[c]){      // 变化lettercount变量lettercounts ++;}if(lettercounts >= t.size()){           // 表示该窗体中已经所有包括t了while(map.find(s[slow]) == map.end() || window[s[slow]] > map[s[slow]]){  // 对窗体进行缩减  1:slow所指向字符不在map中,2:在该子串中                                                                                               //出现非常多次  如BBABC    ABC slow指向Bwindow[s[slow]]--;slow++;}if(minLen > fast - slow + 1){    minLen = fast - slow + 1;result = s.substr(slow, minLen);}window[s[slow]]--;     // 缩减窗体slow++;lettercounts --;}}}return result;}
};

三:Contains Duplicate III

题目:

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.

分析:这道题目也是滑动窗体,滑动窗体一般都是定义一个slow指针,然后一个fast指针不断向前滑动(循环遍历)。这个过程中我们要推断1:是否找到了窗体,2:窗体时否满足要求 3:窗体缩减等

此题也是,设置慢指针l,和快指针i遍历,窗体过大就缩减,判断找到的窗体是否满足要求,技巧是用到了关联容器的lower_bound函数,假设满足要求就返回true,否则返回false。

这里用set或者multiset都一样.。

。注意这里的auto是c++11的新特性。能够用来自己主动类型判断!

class Solution {
public:/*bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {if(nums.size() < 2 || k == 0) return false;multiset<long> windows;       // 滑动窗体int l = 0;for(int i = 0; i < nums.size(); i++){if(i - l > k){     // 窗体大小超过了k 则须要删除nums[l]而且l++windows.erase(nums[l++]);}auto it = windows.lower_bound((long)nums[i] - (long)t);if(it != windows.end() && *it <= ((long)nums[i]+(long)t))    // 用long防止+1溢出return true;windows.insert(nums[i]);}return false;}*/bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {if(nums.size() < 2 || k == 0) return false;set<long> windows;       // 滑动窗体int l = 0;               // 慢指针for(int i = 0; i < nums.size(); i++){if(i - l > k){     // 窗体大小超过了k 则须要删除nums[l]而且l++  窗体须要缩减了windows.erase(nums[l++]);}auto it = windows.lower_bound((long)nums[i] - (long)t);      //  即为nums[i]-t与nums[i]+t之间是否有元素       if(it != windows.end() && *it <= ((long)nums[i]+(long)t))    // 用long防止+1溢出  找到了return true;windows.insert(nums[i]);             // not found}return false;}
};

转载于:https://www.cnblogs.com/yangykaifa/p/6723092.html

leetcode ---双指针+滑动窗体相关推荐

  1. Leetcode双指针滑动窗口相关题目

    滑动窗口 滑动窗口解决哪种问题? 滑动窗口解决给定两个字符串S和T,问你S中是否存在一个子串,包含T中的所有字符并且不含有其他字符. 窗口右指针向右移动,窗口增大,直到满足条件,这时候找到可行解. 窗 ...

  2. leetcode双指针(python与c++)

    1.字符串的排列 思路:双指针+滑动窗口 python: class Solution:def checkInclusion(self, s1: str, s2: str) -> bool:di ...

  3. Leetcode 773. 滑动谜题 C++

    Leetcode 773. 滑动谜题 题目 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示. 一次移动定义为选择 0 与一个相邻的数字(上 ...

  4. 11. Leetcode 713. 乘积小于K的子数组 (数组-同向双指针-滑动窗口)

    给定一个正整数数组 nums和整数 k .请找出该数组内乘积小于 k 的连续的子数组的个数.示例 1:输入: nums = [10,5,2,6], k = 100 输出: 8 解释: 8个乘积小于10 ...

  5. 10. Leetcode 209. 长度最小的子数组 (数组-同向双指针-滑动窗口)

    给定一个含有 n 个正整数的数组和一个正整数 target .找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr ...

  6. LeetCode 1004. 最大连续1的个数 III(双指针+滑动窗口)

    题目描述 给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 . 返回仅包含 1 的最长(连续)子数组的长度. 示例 1: 输入:A = [1,1,1,0,0,0,1 ...

  7. LeetCode 438. 找到字符串中所有字母异位词(双指针+滑动窗口)

    题目描述 给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引. 字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100. ...

  8. LeetCode 424. 替换后的最长重复字符(双指针+滑动窗口)

    题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 注意: 字符串长度 和 k 不会 ...

  9. LeetCode 209. 长度最小的子数组(双指针+滑动窗口)

    题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...

最新文章

  1. 【多标签文本分类】SGM: Sequence Generation Model for Multi-Label Classification
  2. 基于移动机器人的拣货系统研究进展
  3. Webpack入门教程二十九
  4. js 获取 eWebEditor 的内容
  5. 基础算法 —— 高精度计算 —— 高精度除法
  6. Linux系统安装yum源报错256,Redhat Linux RHEL6配置本地YUM源及错误处理
  7. 威纶触摸屏EB8000编程软件V4.65.14 官方最新版
  8. 计算机视觉的算法SIFT算法详细介绍
  9. 蓝天学校计算机教学反思,小学四年级上册《飞向蓝天的恐龙》教学反思
  10. Python3新特性 类型注解 以及 点点点
  11. 科幻电影里的机器人假肢已经照进现实
  12. 下载SAPUI5 SDK
  13. 杭电计算机考研初试经验
  14. 【单片机】Proteus安装、MDK5安装、Proteus与Keil联合仿真教程
  15. 计算机 cf比赛,CF端游PL职业联赛春季赛比赛模式规则介绍
  16. 海量活动邀请函模板,在线就能一键出链接
  17. 太简单,前端也可以写接口了
  18. 今博解盘5.7黄金非农走势分析,黄金原油操作指南及解套在线
  19. MATLAB基于视频的车辆检测方法
  20. 理想、激情、生存———位技术管理人员的20年工作经历和感悟(2)

热门文章

  1. SDL2源代码分析1:初始化(SDL_Init())
  2. 开源网络监控管理系统:OpenNMS
  3. LIRe 源代码分析 4:建立索引(DocumentBuilder)[以颜色布局为例]
  4. 北广传媒RTMP流媒体服务器漏洞
  5. 【w3cschool】MySQL 入门课程_简单复习
  6. java 服务端 处理跨域_javaweb服务端跨域支持
  7. cartographer运行没有map_Cartographer激光SLAM2D源码分析
  8. vmware挂载san存储_戏说 块存储 文件存储 对象存储
  9. 试题2 入门训练 圆的面积
  10. 将ShaderToy中的Shader搬运到Unity