【算法】双指针

作者:指针不指南吗
专栏:算法篇

或许会很慢,但是不可以停下来

文章目录

  • 1.双指针分类
  • 2.双指针思想
  • 3.双指针应用

1.双指针分类

常见问题分类

(1) 对于一个序列,用两个指针维护一段区间, 比如快速排序。

【算法】双指针_第1张图片

(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作。(这种情况比较多)

【算法】双指针_第2张图片


2.双指针思想

//朴素算法 
for(int i=0;i<n;i++)
    	for(int j=0;j<n;j++)
           	······//每道题的具体逻辑

将上面朴素算法的 O( n 2 n^2 n2 ) 优化为 O( n );

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

所以可以想出朴素算法,然后用双指针算法做出优化


3.双指针应用

例题1.

单独输出单词

输入一个字符串,把里面的每个单词输出出来,每个单词之间用空格隔开。

思路

一个指针 i 指向单词的开头,另一个指针 j 指向单词的结尾。

  • 先枚举 i ,然后让 j 指向 i 即单词开头,j++, 直到遇到空格,表示这个单词结束。

  • 输出一个单词结束之后,记得让 i = j ,更新 i , 跳过当前单词,进入下一个的单词开头。

代码实现

#include
using namespace std;

int main()
{
	char s[100010];  //输入一个字符串
	gets(s);
	
	int n=strlen(s);
	
	for(int i=0;i<n;i++){   // 枚举i,i表示一个单词的开头
		int j=i;  
		
		while(j<n&&s[j]!=' ') j++;  //j表示单词的结尾,即不超过字符串的长度,遇到空格表示一个单词结束
		
		//这道题的具体逻辑 
		for(int k=i;k<=j;k++)  cout<<s[k];  //输出单词
		cout<<endl;
		
		i=j;  //令 i 跳过已经输出的单词
	}
	return 0;
}

例题2.

最长连续不重复子序列

给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。

输入格式

第一行包含整数 n。

第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。

输出格式

共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。

数据范围

1≤n≤105

输入样例:

5
1 2 2 3 5

输出样例:

3
  • 思路

    枚举 i 表示区间右端点的指针 , j 表示区间左端点的指针,

    利用区间内数字出现的个数,来判断是否满足条件;

    i 向前走一步,a [ i ] 所表示的数出现的次数多一次,用 s 数组把数字出现的次数存起来;

    j 从 0 开始走,如果在 i 走的过程中 s [ a [ i ] ] > 1,则说明 i 现在表示的数与之前的重复了,

    让 j 往前走,区间挤出去一个数,先 s [ a [ j ] ] --,再 j ++, 直到把重复的数挤出去,即 s [ a [ i ] ] <= 1;

    i 每走一步,判断一下区间大小,是否做出最大值 res 更新;

【算法】双指针_第3张图片

  • 代码实现

    #include
    using namespace std;
    
    const int N=100010;
    int n;
    int a[N],s[N];  //a表示原整数序列,s 表示区间内数字出现的次数
    
    int main()
    {
    	cin>>n;
    	for(int i=0;i<n;i++) cin>>a[i];  //读入数据
    	
    	int res=0,i=0,j=0;  //res 表示最大的区间大小
    	
    	for(i=0;i<n;i++){
    		s[a[i]]++;  //i前进,区间内a[i]的出现次数增加
    		while(s[a[i]]>1){  //若出现重复元素则进入循环
    			s[a[j]]--; //j前进,a[j]出现次数减少一次
    			j++;
    		}
    		res=max(res,i-j+1);	//更新最大值
    	}
    	cout<<res;
    	
    	return 0;
    }
    

你可能感兴趣的:(算法篇,算法,数据结构,c++,排序算法)