最长连续不重复子序列
2021.11.15
原题链接
活动 - AcWing系统讲解常用算法与数据结构,给出相应代码模板,并会布置、讲解相应的基础算法题目。https://www.acwing.com/problem/content/801/双指针的两种情形:
for(i=0,j=0;i<n;i++)
{
while(j<i&&check(i,j))j++;
check为判断性质条件
}
核心思想是
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
O(n*n)
将时间复杂度优化到O(n)
例题
输入 abc def hij 这样含空格的字符,输出字符每遇到一个空格,换行。
int main()
{
string str;
cin >> str;
for (int i = 0; i<str.size(); i++)
{
int j = i;
while (j <str.size()&& str[j] != ' ')j++;
for (int k = i; k < j; k++)cout << str[k];
cout << endl;
i = j;
}
}
原题模板
暴力做法
for(int i=0;i<n;i++)
for(int j=0;j<=i;j++)
if(check(j,i))
res=max(res,j-i+1);
双指针算法
for(int i=0,j=0;i<n;i++)
{
while(j<=i&&check(j,i))j++;
res=max(res,j-i+1);
}
注释
读入数据为 1 2 2 3 5
首先i在1上则s[1]=1;
然后i在2上则s[2]=1;
此时res=2;
然后i在2上则s[2]=2;
此时重复,则更新j的位置,j不停往前移动,直到将重复的元素删除,保证s[a[i]]都等于1
这时候j停止移动,i继续前进,直到i走到最后一个位置,则可以输出res(最大连续不重复元素),时间复杂度为O(n)
代码段
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
int res = 0;
for (int i = 0, j = 0; i < n; i++)
{
s[a[i]] ++;
while (j < i && s[a[i]] > 1) s[a[j++]] --;
res = max(res, i - j + 1);
}
cout << res << endl;
return 0;
}
数组元素的目标和
2021.11.16
原题链接
活动 - AcWing系统讲解常用算法与数据结构,给出相应代码模板,并会布置、讲解相应的基础算法题目。https://www.acwing.com/problem/content/802/
暴力算法
//暴力做法
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a[i]+b[i]==x)
O(nm)
时间复杂度O(NM)
双指针算法
利用数组升序排序的单调性
假设
A 1 2 4 7
B 3 4 6 8 9
x 6
一开始i=0,j=4
由于后面的a[i]>a[0]
而a[0]+b[4]>6,所以必然a[i]+b[4]>6
所以j往前一个位置依旧a[0]+b[3]>6
直到a[0]+b[1]<6这时j=1;
i++;此时在进行如上的操作,最后找到 i=1,j=1满足
时间复杂度O(N+M)
代码段
int main()
{
scanf("%d%d%d", &n, &m, &x);
for (int i = 0; i < n; i++)scanf("%d", &a[i]);
for (int i = 0; i < n; i++)scanf("%d", &b[i]);
for (int i = 0, j = m - 1; i < n; i++)
{
while (j >= 0 && a[i] + b[i] > x)j--;
if (a[i] + b[j] == x)
{
printf("%d %d\n", i, j);
break;
}
}
}
判断子序列
2021.11.17
原题链接
2816. 判断子序列 - AcWing题库高质量的算法题库https://www.acwing.com/problem/content/2818/
解释
找到一种a[i]和b[j]的匹配模式,即a[i]=b[j],如果在b[j]中找到全部的a[i],则输出YES
时间复杂度O(n)
代码段
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)scanf("%d", &a[i]);
for (int i = 0; i < n; i++)scanf("%d", &b[i]);
int i = 0, j = 0;
while (i < n && j < m)
{
if (a[i] == b[j])i++;
j++;
}
if (i == n)puts("YES");
else puts("NO");
}