双指针运算,位运算
**双指针的算法一般会降低复杂度,进而提高效率
那么优势是什么呢? 他可以将时间复杂度由o(n*n) 降低为o(n) ** 进而提高效率
那么下面是一道题目
\799. 最长连续不重复子序
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。
输入格式
第一行包含整数 n。
第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。
输出格式
共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。
数据范围
1≤n≤105
输入样例:
5
1 2 2 3 5
输出样例:
3
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[N],s[N];
int main()
{
int n;
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(j < i && s[a[i]] > 1) s[a[j++]]--;
res = max(res,i-j+1);
}
cout << res << endl;
return 0;
}
双指针较为简单
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N],b[N];
int main()
{
int n,m,x;
cin >> n >> m >> x;
for(int i = 0;i<n;i++)
{
cin >> a[i];
}
for(int i = 0;i<m;i++)
{
cin >> b[i];
}
for(int i = 0,j = m-1;i<n;i++)
{
while(j >= 0 && a[i] + b[j] > x) j--;
if(j >= 0 && a[i] + b[j] == x) cout << i << ' ' << j << endl;
}
return 0;
}
这个是运用双指针计算数组元素的目标和
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N],b[N];
int main()
{
int n,m;
cin >> n >> m;
for(int i = 0;i<n;i++) cin >> a[i];
for(int i = 0;i<m;i++) cin >> b[i];
int j = 0;
for(int i = 0;i<m;i++)
{
if(j < n && a[j] == b[i]) j++;
}
if(j == n)
cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
这个是判断子序列的编程方法
以上就是双指针运算了
下面就是重头戏,就是位数运算
想到双指针,就会想到lowbit(x)这个东西
那么什么是lowbit原理呢?
一下为lowbit 的含义:
表示取得整数x的二进制表示中,从右边往左的第一个1以及其后全部0所组成的那部分数值
及可以理解为 只保留x 的最右边的那个1 ,其余位全部清零。
实际上是 x & (-x):
• 在计算机中,负数以补码形式存储。若 x 的二进制是 bxxxx1000(其中 bxxxx 可以理解为前面的若干位),
则 -x 的二进制会是其反码加 1,即再一次把相同位置的最低位 1 提取出来。
• 与运算 x & (-x) 只保留了从右往左遇到的第一个 1 所在位置上的值,其余位全部变为 0。
好的,那么现在理解了什么是lowbit ,那就练习一道题目试一试叭!
假设我有一个数,我要求其二进制1的个数是多少
#include <iostream>
using namespace std;
// 函数:获取 x 的最低位 1 以及其后所有 0 组成的数值
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 不为 0 时,继续提取最低位 1
x -= lowbit(x);
res++; // 每去掉一个最低位 1,就计数 +1
}
cout << res << ' ';
}
return 0;
}
不知道你们理解了没有,现在我举一个例子吧
比如我输入 31
那么 31 对应的二进制是 11111
现在逐层 去掉最低位 1
\1. lowbit(31) = 1,x = 31 - 1 = 30,res = 1
\2. lowbit(30) = 2,x = 30 - 2 = 28,res = 2
\3. lowbit(28) = 4,x = 28 - 4 = 24,res = 3
\4. lowbit(24) = 8,x = 24 - 8 = 16,res = 4
\5. lowbit(16) = 16,x = 16 - 16 = 0,res = 5
• 最终 res = 5
x & (-x). 这个地方着重理解,非常不错的一个点啊!!!