目录
一、双指针算法
二、位运算
三、区间合并
一、双指针算法
双指针算法模板:
for(int i = 0,j = 0;i < n;i++)
{
while(j < i && check(i,j)) j++;
//每道题的具体逻辑
}
- 1.1两个指针指向两个队列
- 1.2两个指针指向一个队列
案例习题:
分割字符串
#include<iostream>
using namespace std;
int main()
{
char str[1000];
gets(str); //gets会读取空格,而不读取回车
int n = strlen(str);
for(int i = 0;i < n;i++){
int j = i;
while(j < n && str[j] != ' ') j++;
//这道题的具体逻辑
for(int k =i;k < j;k++){
cout<<str[k];
}
cout<<endl;
}
return 0;
}
最大不重复子序列:
#include<iostream>
using namespace std;
const int N = 100010;
int a[N];
int s[N];
int main()
{
cin>>n;
for(int i= 0;i < n;i++) cin>>a[i];
int res = 0;
for(int i = 0,j = 0;i < n;i++)
{
s[a[i]]++;
while(s[a[i]] > 1)
{
s[a[j]] --;
j ++;
}
res = max(res,i - j + 1);
}
cout<<res<<endl;
return 0;
}
二、位运算
常见操作:
n的二进制表示中第k位是几(n>>k&1)
1、先把第k位移到最后一位(n >> k)
2、看个位是几(n &1)
#include<iostream>
using namespace std;
int main()
{
int n = 10;
for(int k = 3;k>=0;k--)
{
cout<<(n >> k & 1)<<endl;
}
return 0;
}
lowbit(x):返回x的最后一位1
例:x=1010,lowbit(x)返回10
x=101000,lowbit(x)返回1000
lowbit(x)的基本应用,求二进制数x中1的个数
#include<iostream>
using namespace std;
int lowbit(int x)
{
return x & -x;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
int res = 0;
while(x) x -= lowbit(x),res ++; //每次减去x的最后一位1
cout<<res<<endl;
}
return 0;
}
三、区间合并
将所有存在交集的区间合并
步骤:
1、按区间左端点排序
2、扫描整个区间,扫描过程当中检查与其他区间的关系
3、 对区间进行合并
案例习题代码:
#include<iostream>
#include<algorithm>
#include<vector> //用vector来存储区间
using namespace std;
const int N = 100010;
typedef pair<int,int> PII;
int n;
vector<PII> segs;
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;
}
int main()
{
cin>> n;
for(int i =0;i<n;i++)
{
int l,r;
cin>>l>>r;
segs.push_back({l,r});
}
merge(segs);
cout<<segs.size()<<endl;
return 0;
}