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;
}
};
题目:
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指向B
window[s[slow]]--;
slow++;
}
if(minLen > fast - slow + 1){
minLen = fast - slow + 1;
result = s.substr(slow, minLen);
}
window[s[slow]]--; // 缩减窗体
slow++;
lettercounts --;
} } }
return result;
}
};
题目:
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; }
};
leetcode ---双指针+滑动窗体的更多相关文章
- Qt使用QGraphicsView实现滑动窗体效果
QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容.QGraphicsScene提供了QGraphicsItem的容器功能.通常与QGraphicsView一起使用来描 ...
- 滑动窗体的最大值(STL的应用+剑指offer)
滑动窗体的最大值 參与人数:767时间限制:1秒空间限制:32768K 通过比例:21.61% 最佳记录:0 ms|8552K(来自 ) 题目描写叙述 给定一个数组和滑动窗体的大小.找出全部滑动窗体里 ...
- TCP/IP具体解释--TCP/IP可靠的原理 滑动窗体 拥塞窗体
TCP和UDP处在同一层---运输层,可是TCP和UDP最不同的地方是,TCP提供了一种可靠的数据传输服务,TCP是面向连接的,也就是说,利用TCP通信的两台主机首先要经历一个"拨打电话&q ...
- 【剑指Offer学习】【面试题65:滑动窗体的最大值】
题目:给定一个数组和滑动窗体的大小,请找出全部滑动窗体里的最大值. 举例说明 比如,假设输入数组{2,3,4,2,6,2,5,1}及滑动窗体的大小.那么一共存在6个滑动窗体,它们的最大值分别为{4,4 ...
- C++双指针滑动和利用Vector实现无重复字符的最长子串—力扣算法
题目: 力扣原题链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/ 给定一个字符串, ...
- TCP滑动窗体
TCP的滑动窗体攻克了端到端的流量控制问题,同意接受方对传输进行限制.直到它拥有足够的缓冲空间来容纳很多其他的数据.滑动窗体的大小由接收方确定,接收方在发送确认信号给发送方的同一时候告诉发送方自己的缓 ...
- 【转】Appium测试安卓Launcher以滑动窗体获得目标应用
原文地址:http://blog.csdn.net/zhubaitian/article/details/39755553 所谓Launcher,指的是安卓的桌面管理程序,所有的应用图标都放在laun ...
- 【leetcode 239. 滑动窗口最大值】解题报告
思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...
- Leetcode 480.滑动窗口中位数
滑动窗口中位数 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) ...
随机推荐
- 如何设置qt creator的快捷键
如何设置qt creator快捷键 以设置设置edit - select encoding的快捷键为例 1. tools - options - environment - keyborad 2.在搜 ...
- HDU4666+POJ2926【最远曼哈顿距离】
一开始就明白那个N*1<k的算法了, 可无奈删除操作耗时还是太多,最后学习了STL set,map相应的用法,方便好多. STL真的是一个好工具 #include<iostream> ...
- Java从零开始学二十九(大数操作(BigIntger、BigDecimal)
一.BigInteger 如果在操作的时候一个整型数据已经超过了整数的最大类型长度long的话,则此数据就无法装入,所以,此时要使用BigInteger类进行操作. 不可变的任意精度的整数.所有操作中 ...
- flume hdfs一些简单配置记忆
############################################ # producer config ##################################### ...
- 栈溢出笔记1.3 准备Shellcode
经过1.1和1.2节的讲述,我们已经知道了怎样更改EIP的值. 程序运行函数之后将跳转到我们设定的位置開始运行,因此,我们须要准备一个自己的程序,接手后面的工作.这是一个什么样的程序?是一个C语言编写 ...
- Spring <context:annotation-config/> 说明
在基于主机方式配置Spring的配置文件中,你可能会见到<context:annotation-config/>这样一条配置,他的作用是式地向 Spring 容器注册AutowiredAn ...
- 【Linux】在Linux上查看并替换特殊字符
现有windows上新建的一个txt文件file01.txt,内容如下: 我们通过ftp上传到Linux,在Linux下使用命令cat –A file01.txt查看文件内容发现该文件的结尾全是^M$ ...
- python学习笔记之函数(方法)
def func(x): print 'x is', x x = 2 print 'Changed local x to', x x = 50 func(x) print 'x is still', ...
- (转)Content-Disposition的使用和注意事项
最近不少Web技术圈内的朋友在讨论协议方面的事情,有的说web开发者应该熟悉web相关的协议,有的则说不用很了解.个人认为这要分层次来看待这个问 题,对于一个新手或者刚入门的web开发人员而言,研究协 ...
- linux修改 时间 时区
linux系统修改系统时间与时区 | 浏览:3486 | 更新:2014-06-18 19:36 1 2 3 4 5 6 7 分步阅读 有装过Linux系统的人,可能都会有这样的经历,就是该机器安装w ...