双指针问题(同向)
一、有序数组去重
问题描述:
删除有序数组中所有重复的数据
输入:
第一行整数n表示有n个数(n<10000000),第二行n个整数x(0<x<9999999999999)
输出:
一行,去重后的数列,用空格隔开
思考:
1.考虑使用数组统计法,但是数据范围(0<×<9999999999999)范围过大,统计数组开不了这么大
2.考虑使用传统方法统计去重复,但是数据个数(n<10000000)双重循环会导致超时,好在他是有序的,可以使用双指针维护一个窗口,O(n)的时间处理这个问题
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{long long n;cin>>n;long long a[11000000];for(int i = 0;i<n;i++){cin>>a[i];}int slow = 0;for(int i = 0;i<n;i++){if(a[slow]!=a[i]) a[++slow] = a[i];}for(int i = 0;i<=slow;i++){cout<<a[i]<<" ";}return 0;
}二、移除元素
问题描述:
删除数组(非有序)中所有等于x的数据
输入:
第一行整数n表示有n个数(n<10000000),第二行n个整数d(0<d<9999999999999)
第三行要删除的元素x
输出:
一行,删除后的数列,用空格隔开
思考:
1.数组不能打乱原有的顺序,所以不能使用数组统计法去掉要删除的数据
2.常规删除需要移动其之后的所有数据,时间复杂度为O(n平方)会超时可以使用双指针一次性去掉所有要删除的元素
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{long long n;cin>>n;long long a[11000000];for(int i = 0;i<n;i++){cin>>a[i];}long long p;cin>>p;int slow = 0;for(int i = 0;i<n;i++){if(a[i]!=p) {a[slow++] = a[i];}}for(int i = 0;i<slow;i++){cout<<a[i]<<" ";}return 0;
}三、无重复字符的最长子串
问题描述
给定字符串s,找到其最长子串的长度,该子串需满足所有字符不重复。例如:
"abcabcbb"→输出3(子串“abc")
"pwwkew”→输出3(子串“wke")
输入
一个字符串
输出
一个整数,无重复字符的最长子串的长度
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string.h>
using namespace std;
bool ifcf(string);
int main()
{string a;cin>>a;int n = a.size();int ma = -1;string mas = "";for(int i = 0;i<n;i++){for(int j = i;j<n;j++){string z = a.substr(i,j-i+1);if(ifcf(z)==true){int l = z.size();if(ma<l){ma = l;mas = z;}}}}cout<<mas;return 0;
}
bool ifcf(string s)
{int cnt[130]={0};for(int i = 0;i<s.size();i++){cnt[s[i]]++;if(cnt[s[i]]>1) return false;}return true;
}