leetcode ---双指针+滑动窗体
一: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 ---双指针+滑动窗体相关推荐
- Leetcode双指针滑动窗口相关题目
滑动窗口 滑动窗口解决哪种问题? 滑动窗口解决给定两个字符串S和T,问你S中是否存在一个子串,包含T中的所有字符并且不含有其他字符. 窗口右指针向右移动,窗口增大,直到满足条件,这时候找到可行解. 窗 ...
- leetcode双指针(python与c++)
1.字符串的排列 思路:双指针+滑动窗口 python: class Solution:def checkInclusion(self, s1: str, s2: str) -> bool:di ...
- Leetcode 773. 滑动谜题 C++
Leetcode 773. 滑动谜题 题目 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示. 一次移动定义为选择 0 与一个相邻的数字(上 ...
- 11. Leetcode 713. 乘积小于K的子数组 (数组-同向双指针-滑动窗口)
给定一个正整数数组 nums和整数 k .请找出该数组内乘积小于 k 的连续的子数组的个数.示例 1:输入: nums = [10,5,2,6], k = 100 输出: 8 解释: 8个乘积小于10 ...
- 10. Leetcode 209. 长度最小的子数组 (数组-同向双指针-滑动窗口)
给定一个含有 n 个正整数的数组和一个正整数 target .找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr ...
- LeetCode 1004. 最大连续1的个数 III(双指针+滑动窗口)
题目描述 给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 . 返回仅包含 1 的最长(连续)子数组的长度. 示例 1: 输入:A = [1,1,1,0,0,0,1 ...
- LeetCode 438. 找到字符串中所有字母异位词(双指针+滑动窗口)
题目描述 给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引. 字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100. ...
- LeetCode 424. 替换后的最长重复字符(双指针+滑动窗口)
题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 注意: 字符串长度 和 k 不会 ...
- LeetCode 209. 长度最小的子数组(双指针+滑动窗口)
题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...
最新文章
- 【多标签文本分类】SGM: Sequence Generation Model for Multi-Label Classification
- 基于移动机器人的拣货系统研究进展
- Webpack入门教程二十九
- js 获取 eWebEditor 的内容
- 基础算法 —— 高精度计算 —— 高精度除法
- Linux系统安装yum源报错256,Redhat Linux RHEL6配置本地YUM源及错误处理
- 威纶触摸屏EB8000编程软件V4.65.14 官方最新版
- 计算机视觉的算法SIFT算法详细介绍
- 蓝天学校计算机教学反思,小学四年级上册《飞向蓝天的恐龙》教学反思
- Python3新特性 类型注解 以及 点点点
- 科幻电影里的机器人假肢已经照进现实
- 下载SAPUI5 SDK
- 杭电计算机考研初试经验
- 【单片机】Proteus安装、MDK5安装、Proteus与Keil联合仿真教程
- 计算机 cf比赛,CF端游PL职业联赛春季赛比赛模式规则介绍
- 海量活动邀请函模板,在线就能一键出链接
- 太简单,前端也可以写接口了
- 今博解盘5.7黄金非农走势分析,黄金原油操作指南及解套在线
- MATLAB基于视频的车辆检测方法
- 理想、激情、生存———位技术管理人员的20年工作经历和感悟(2)
热门文章
- SDL2源代码分析1:初始化(SDL_Init())
- 开源网络监控管理系统:OpenNMS
- LIRe 源代码分析 4:建立索引(DocumentBuilder)[以颜色布局为例]
- 北广传媒RTMP流媒体服务器漏洞
- 【w3cschool】MySQL 入门课程_简单复习
- java 服务端 处理跨域_javaweb服务端跨域支持
- cartographer运行没有map_Cartographer激光SLAM2D源码分析
- vmware挂载san存储_戏说 块存储 文件存储 对象存储
- 试题2 入门训练 圆的面积
- 将ShaderToy中的Shader搬运到Unity