刷题模板-区间合并、单调栈、滑动窗口、前缀和

 1、区间合并

       之前网易面试的时候遇到过区间合并的问题,结果不会做,进行把y总的课的区间合并部分看了以下,简单记录以下模板,以便于后面学习使用。

主要的思路就是:

1、先对所有区间的左端点进行排序。

2、然后进行区间合并(只有三种情况)

第一种情况:当前需合并区间 和  当前维护区间没有交集。

第二种情况:当前需合并区间 和  当前维护区间有交集。

第三种情况:当前需合并区间 被  当前维护区间包含。

#include<bits/stdc++.h>
using namespace std;

typedef pair<int, int> PII;
int n;


void merge(vector<PII>& segs){
    vector<PII> ans;
    sort(segs.begin(), segs.end());
    // 定义初始维护区间
    int st = INT_MIN, ed = INT_MIN;
    for(auto& seg : segs){
        if(ed < seg.first){
            // 说明当前的seg 和 当前维护的区间 没有交集
            if(st != INT_MIN) ans.push_back({st, ed});
            // 更新 当前维护的区间
            st = seg.first;
            ed = seg.second;
        }else{
            // 说明当前的seg 和 当前维护的区间 有交集
            ed = max(ed, seg.second);
        }
    }
    // 将最后一个维护的区间进行存储
    if(st != INT_MIN) ans.push_back({st, ed});
    segs = ans;
}

int main(){
    cin>>n;
    int l, r;
    vector<PII> segs; 
    while(n--){
        cin>>l>>r;
        segs.push_back({l, r});
    }// end while
    merge(segs);
    cout<<segs.size()<<endl;
    return 0;
}

2、单调栈 

最近做leetcode遇到了一些单调栈的问题,所以先简单记录一下模板,后续在进行补充:

#include<bits/stdc++.h>
using namespace std;


/*
    例如涉及一个题目:
    找到当前数组中 
                 1、比当前数字小的 
                 2、并且在当前数字左边的 
                 3、离当前数字最近
    的对应数字的下标(没找到用-1代替)

    思路:就是维护一个单调递增的栈
*/

int main(){
    // 答案为:[-1, 0, -1, -1, 3, 4, 3]
    vector<int> nums = {4, 5, 2, 1, 7, 10, 3};
    stack<int> stk;
    vector<int> ans;

    int size = nums.size();

    for(int i=0; i<size; i++){
        int num = nums[i];
        while(!stk.empty() and num <= nums[stk.top()]){    
            stk.pop();
        }
        int index = stk.empty() ? -1 : stk.top();
        ans.push_back(index);
        stk.push(i); 
    }
    
    for(auto& num : ans) cout<<num<<" ";
    return 0;
}


/*
    模板就是:
    // 有些题目是进行倒叙的遍历
    for(int i=0; i<size; i++){
        while(!stk.empty() and check()){
            // 具体的操作
        }
        // 具体的操作
        stk.push(i);  // 入栈
    }
*/

3、 滑动窗口

滑动窗口的题在找实习面试的时候暂时还没有遇到过,自己做了之后主要总结为:

1、在求子串问题时进行出现。

2、在出现数字全为正数的时候会出现比较多,出现负数可以考虑前缀和。

/*
    只是简单写一下模板
*/

int size = s.size();
int l=0, r=0;
// 我习惯维护一个闭区间 [l, r]
while(r < size){
    while(l<r and check()){
        // 具体的操作 目的是:移动左边界 l++
    }
    
    // 具体的操作    
    r++; // 在最后进行r++ 移动右边界。
}

 4、前缀和

前缀和还没有进行很好的总结过,先记录一下模板,后续有总结再进行补充:

/*
    只对前缀和 数组的生成 进行模板
    prefixSum[i] 表示前i个数字的和
*/
int size = nums.size();
vector<int> prefixSum(size+1, 0);
for(int i=1; i<=size; i++){
    prefixSum[i] = prefixSum[i-1] + nums[i-1];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值