双指针
for (int i = 0, j = 0; i < n; i ++ )
{
while (j < i && check(i, j)) j ++ ;
// 具体问题的逻辑
}
常见问题分类:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
离散化
1.要求保序
离散化前 x<y,离散化后要求f(x)<f(y)
步骤,排序,去重,二分
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
}
2.不要求保序
使用map,或者unordered_map, 实际上就是一个hash 函数
int num=0;
unordered_map<int,int> hash;
int get(int x){
if(hash.count(x)!=0) return hash[x];
return hash[x]=++num;
}
区间融合
void merge(vector<PII> &v){
sort(v.begin(),v.end());
if(v.empty()) return;
vector<PII> temp;
int l1=v[0].first,r1=v[0].second;
for(auto item:v){
if(item.first<=r1) r1=max(r1,item.second);
else {
temp.emplace_back(l1,r1);
l1=item.first;
r1=item.second;
}
}
temp.emplace_back(l1,r1);
v=temp;
}