双指针,离散化和区间合并
双指针
时间复杂度普遍为O(n)
for (int i = 0, j = 0; i < n; i ++ )
{
while (j < i && check(i, j)) j ++ ;
// 具体问题的逻辑
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 30;
int a[N];
string s;
int main() {
cin >> s;
int res = 0;
for (int i = 0, j = 0; i < s.size(); i ++ ) {
a[s[i] - 'a'] ++;
while (j < i && a[s[i] - 'a'] > 1) {
a[s[j] - 'a'] --;
j ++;
}
res = max(res, i - j + 1);
}
cout << res << endl;
return 0;
}
常见问题分类:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
离散化
对于大范围,但是数据少的题,如果直接开相应数组大小的话,时空可能会爆掉,所以可以将无限的空间,映射成有限的空间,一一对应。
思路是:
1.先排序
2.再删除重复元素
3.最后就是索引元素离散化后对应的值。
vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 去掉重复元素
// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
int l = 0, r = alls.size() - 1;
while (l < r)
{
int mid = l + r >> 1;
if (alls[mid] >= x) r = mid;
else l = mid + 1;
}
return r + 1; // 映射到1, 2, ...n
}
区间合并
1.先对区间头进行排序
2.然后持续更新尾部
// 将所有存在交集的区间合并
void merge(vector<PII> &segs)
{
vector<PII> res;
sort(segs.begin(), segs.end());
int st = -2e9, ed = -2e9;
for (auto seg : segs)
if (ed < seg.first)//如果没有交集
{
if (st != -2e9) res.push_back({st, ed});//加入第一段区间
st = seg.first, ed = seg.second;//更新头尾值
}
else ed = max(ed, seg.second);//更新最大的尾值
if (st != -2e9) res.push_back({st, ed});
segs = res;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】