位运算
整数转二进制:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n = 10;
for (int i = 3; i >= 0; i--)
cout << (n >> i & 1);//1010
return 0;
}
返回整数二进制的最后一位1:
#include<iostream>
using namespace std;
int main()
{
int n = 10;//1010
cout << (n & (-n));//打印出来的2==10(后两位)
return 0;
}
统计整数二进制1的个数:
#include<iostream>
using namespace std;
int lowbit(int x)
{
return x & (-x);
}
int main()
{
int n = 10, cnt = 0;
while (n)
{
n -= lowbit(n);
cnt++;
}
cout << cnt;//输出为2
return 0;
}
双指针算法
#include<iostream>
#include<algorithm>
using namespace std;
int a[100005],s[100005];
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 (s[a[i]] > 1)
{
s[a[j]]--;
j++;
}
res = max(res, i - j + 1);
}
cout << res;
return 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);
}
i每次往后移动,移动过程中对i指针所指的元素在s数组中++,s[a[i]]表示a[i]元素在从j到i这一段中出现过的次数,接着进行判断,如果s[a[i]]>1,也就是说明该元素重复,但之前出现的和a[i]相同的元素在哪还要判断,这就进入了while循环,每次先对s[a[j]]–,表示j从这一段子区间中剔除掉,在这一段子区间出现次数–,接着j向右移动一个,继续判断,知道s[a[i]]<=1,表示重复的元素已经剔除,i可以继续移动了。
比如e:1 2 2 4 5
i,j开始指向a[0]==1,接着i移动到1,移动到2,这时候发现s[a[i]]>1,所以j向右移动到a[1]==2,剔除掉a[0]==1,a[i]<=1还是不满足,说明重复元素仍然存在,继续j++,移动到a[2]==2,剔除掉a[1]==2,这时候s[a[i]]<=1,i++继续移动.
例题链接-- 数组元素的目标和
#include<iostream>
#include<algorithm>
using namespace std;
int a[100005],b[100005];
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 (a[i] + b[j] == x) {
cout << i << " " << j;
break;
}
}
return 0;
}