双指针算法

联想归并排序,快排

目的:优化到O(n)  提高效率  O(n方)优化到O(n)

一个小例子,输入abc def ghi然后输出三行分别输出这三个单词

 1 #incldue <iostream>
 2 #include <string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     char str[1000];
 7     gets(str);
 8     int n=strlen(str);
 9     for(int i=0;i<n;i++)//也可以写成(int i=0;str[i];i++) 
10     {
11         int j=i;//j和i都先放到第一个地方
12         while(j<n&&str[j]!='')
13         {
14             j++;    
15         } 
16         //这道题的具体逻辑 
17         for(int k=i;k<j;k++)
18         {
19             cout<<str[k];//首先输出abc 
20         }
21         i=j;
22     }
23     return 0;
24 }

 

最长连续不重复子序列

给定一个长度为 &amp;amp;amp;amp;amp;amp;amp;lt;span id="MathJax-Span-2" class="mrow"&amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;span id="MathJax-Span-3" class="mi"&amp;amp;amp;amp;amp;amp;amp;gt;n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度:

输入样例:

5
1 2 2 3 5

输出样例:

3    (即235)

标准答案:
 1 #include <iostream>
 2 using namespace std;
 3 const int N=100010;
 4 int n;
 5 int q[N],s[N];
 6 int main()
 7 {
 8     scanf("%d",&n);
 9     for(int i=0;i<n;i++)
10     {
11         scanf("%d",&q[i]);
12     }
13     int res=0;
14     for(int i=0,j=0;i<n;i++)
15     {
16         s[q[i]]++;
17         while(j<i&&s[q[i]]>1)
18         {
19             s[q[j++]]--;
20         }
21         res=max(res,i-j+1);
22     }
23     cout<<res<<endl;
24     return 0;
25 }

 ----------------------------------- ----------------------------------- ----------------------------------- ----------------------------------- ----------------------------------- ------------------------------

数组元素的目标和:

答案:

#include <iostream>
using namespace std;
const int N=100010;
int n,m,x;
int a[N],b[N];
int main()
{
scanf("%d%d%d",&n,&m,&x);//输入基础
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);//输入a数组
}
for(int i=0;i<m;i++)
{
scanf("%d",&b[i]);//输入b数组
}
for(int i=0,j=m-1;i<n;i++)//i从a数组第一个开始 j从b数组最后一个开始
{
while(j>=0&&a[i]+b[j]>x)//j要>=0,先找出不符合条件的范围
{
j--;//j一直左移 直到适当的位置
}
if(j>=0&&a[i]+b[j]==x)//找到答案
{
cout<<i<<' '<<j<<endl;
}
}
return 0;
}

 

求取两个数组中 一个数组的一个值加上另外一个数组
的一个值等于一个特定值 找到对应的i和j
一般思路 先找第一个数组的第一个值 然后循环遍历第二个数组的每一个值
然后找到答案 输出第一个数组的i和第二个数组的j

算法思路 依旧从第一个数组的第一个值开始遍历
第二个数组从后往前来 虽然从后往前也行
然后找到两个值相加大于x的情况 就是不要的情况
然后找到答案就输出
要是相加小于x就不管 因为越往左 下面的数组值越小 就不可能有答案

其实两种思路差不多

------------------------------------------------------------------------------------------------------------------------------------------------------

 判断子序列:

两个数组   判断第一个数组是不是第二个数组的子序列     第一个数组可以在第二个数组中不紧挨着,中间可以放其他数字 只要保证数组a的顺序不变就行

思路:

有上下两个数列
判断第一个数列是不是第二个数列的子序列
如何判断?
首先从第一个数列的第一个数开始
对应第二个数列的第一个数
第二个数列从第一个数开始遍历
直到数字与第一个数列的第一个数相同
若不同第二个数列遍历 j++
相同之后 i也++ j也++
i一直遍历不回头 j也是
然后匹配完毕 i等于n时 就匹配完毕
输出yes或者no
匹配完毕就输出yes 否则no

 

 

 

 

答案:

 1 //数组元素的目标和
 2 #include <iostream>
 3 using namespace std;
 4 const int N=100010;
 5 int n,m,x;
 6 int a[N],b[N];
 7 int main()
 8 {
 9     scanf("%d%d%d",&n,&m,&x);
10     for(int i=0;i<n;i++)
11     {
12         scanf("%d",&a[i]);
13     }
14         for(int i=0;i<m;i++)
15     {
16         scanf("%d",&b[i]);
17     }
18     for(int i=0,j=m-1;i<n;i++)
19     {
20         while(j>=0&&a[i]+b[j]>x)
21         {
22             j--;
23         }
24         if(j>=0&&a[i]+b[j]==x)
25         {
26             cout<<i<<' '<<j<<endl;
27         }
28     }
29     return 0;
30 } 

 

posted @ 2023-08-12 17:26  宠柳娇花  阅读(22)  评论(0)    收藏  举报