双指针,离散化和区间合并

双指针

时间复杂度普遍为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;
}
posted @   帝宝单推人!  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示