位运算+双指针算法

位运算

整数转二进制:

#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;
}

猜你喜欢

转载自blog.csdn.net/weixin_50816938/article/details/118940756