双指针算法

title: 双指针算法
date: 2019-05-26 23:45:09
tags: 双指针算法

双指针算法

主要是两大类:
模板:

for(i=0,j=0;i<n;i++)
{
	while(j<i&&check(i,j))
	j++;
	//每道题目的具体逻辑
}

核心思想:
将一个 O ( n 2 ) O(n^2) O(n2) 的算法 优化成 O ( n ) O(n) O(n)

for(int i=0;i<n;i++)
	for(int j=0;j<n;j++)
	
-->

for(i=0,j=0;i<n;i++)
{
	while(j<i&&check(i,j))//看似依然是两重循环,但是i,j移动的距离最多为n,所以总共最多为2n
	j++;
	//每道题目的具体逻辑
}

eg:
输入:
abc deg gh

输出:
abc
deg
gh

#include <iostream>
#include <cstring>
const int maxn=1e3+5;
using namespace std;
int main()
{
	//string s;
	//cin>>s; 注意string是以空格停止读入的 
	//cout<<s<<endl;
	char s[maxn];
	gets(s);
	for(int i=0;i<strlen(s);)
	{
		int j=i;
		while(j<strlen(s)&&s[j]!=' ')
		j++;//j总是指向一个单词结束之后的那个位置 
		
		for(int k=i;k<j;k++)
		cout<<s[k];
		cout<<endl;
		i=j+1;
	}
	return 0;
}

应用:快排的划分,归并的归并部分,KMP算法等

一般都能够先想出一个 O ( n 2 ) O(n^2) O(n2) 朴素做法,然后可以改用双指针

例题:
给定一个长度为n(<1e5)的整数序列,请找出最长的不包含重复数字的连续区间,输出它的长度。
输入:
5
1 2 2 3 5
输出:
3
注意到这个单调性(具体表现为j++),并进行优化,是本题关键
所有本题 可以用单调队列来做,如果范围很大,不能直接开那么大的数组,可以用哈希表

#include <iostream>
#include <cstring>
const int maxn=1e5+5;
using namespace std;
int cnt[maxn],a[maxn];//cnt用于动态的记录当前区间内a[i]的个数
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++)
	{
		cnt[a[i]]++;//i指向右端点,j指向左端点 
		while(cnt[a[i]]>1)//说明区间内有重复元素,注意 这里是a[i] 
		{				//j是随着i往右移的 
			cnt[a[j]]--;
			j++;
		}
		res=max(res,i-j+1); 
	}
	cout<<res<<endl;
	return 0;
}


此时 cnt[a[i]]=2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值