双指针算法
例题:
现有多个单词 用空格隔开 将每个单词分别输出
输入:
abc def gh
输出:
abc
def
gh
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
char str[1000];
gets(str);
int n = strlen(str);
for(int i = 0; i < n; ++ i)
{
int j = i;
while(j < n && str[j] != ' ') j++;
for(int k = i; k < j; ++ k) cout << str[k];
cout << endl;
i = j;//i在for循环里还会++ 所以会指向下一个单词的开始
}
return 0;
}
acwing 799最长连续不重复子序列
题目描述
给定一个长度为n的整数序列,请找出最长的不包含重复数字的连续区间,输出它的长度。
输入格式
第一行包含整数n。
第二行包含n个整数(均在0~100000范围内),表示整数序列。
输出格式
共一行,包含一个整数,表示最长的不包含重复数字的连续子序列的长度。
数据范围
1≤n≤100000
样例
输入样例:
5
1 2 2 3 5
输出样例:
3
双重循环O(n ^ 2)做法:
//朴素做法
for(int i = 0; i < n; ++ i) // i模拟的是最长子序列的终点
for(int j = 0; j <= i; ++ j) // j模拟的是最长子序列的起点
if(check(j,i))
{
res = max(res, j - i + 1);
}
要明白 j 是 不可能往前走的
比如 某一轮的循环结果是 4 - 7 那说明 4 -7 无重复元素 但是 3 - 7 是有重复元素的
如果i从7到8往后了一位, 你的j从4到3 向前了一位 那说明 3 - 8区间内无重复元素 那 3 - 7 就也不应该有重复元素 与前面的结论矛盾.
//双指针算法代码 O(n)
for(int i = 0, j = 0; i < n; ++ i)
{
while(j <= i && check(j,i)) ++ j;
res = max(res, j - i + 1);
}
#include <iostream>
using namespace std;
const int N = 100010;
int n;
int a[N], s[N]; // s数组记录每个数出现的次数
int main()
{
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 << endl;
return 0;
}