双指针算法
联想归并排序,快排
目的:优化到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;lt;span id="MathJax-Span-2" class="mrow"&amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;span id="MathJax-Span-3" class="mi"&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 }
浙公网安备 33010602011771号