双指针(滑动窗口)相关算法题
双指针算法有时候也叫尺取法或者滑动窗口,是⼀种优化暴力枚举策略的手段:当我们发现在两层 for 循环的暴力枚举过程中,两个指针是可以不回退的,此时我们就可以利用两个指针不回退的性质来优化时间复杂度。因为双指针算法中,两个指针是朝着同一个方向移动的,因此也叫做同向双指针。
1.

#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long LL;
const int N=1e6+10;
LL arr[N];
int T,n;
int main()
{cin >> T;while(T--){unordered_map<int,int> mp;cin >> n;for(int i=1;i<=n;i++){cin >> arr[i];}int left=1;int right=1;int ret =0;while(right<=n){mp[arr[right]]++;while(mp[arr[right]]>1){mp[arr[left]]--;left++;}ret=max(ret,right-left+1);right++;}cout << ret << endl;}return 0;
}
2.
#include <iostream>
#include <unordered_map>
using namespace std;
const int N=1e6+10;
int arr[N];
int n,m,cnt;
int L,R;
unordered_map<int,int> mp;
int main()
{cin >> n >> m;for(int i=1;i<=n;i++){cin >> arr[i];}int left=1;int right=1;int ret=n+1;while(right <= n){mp[arr[right]]++;if(mp[arr[right]]==1){cnt++;}while(cnt==m){mp[arr[left]]--;if(mp[arr[left]]==0){cnt--;}if(right-left+1<ret){L=left;R=right;ret=right-left+1;}left++;}right++;}cout << L << " " << R << endl;return 0;
}
3.
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
const int N=1e6+10;
string s;
int cnt;
unordered_map<char,int> mp;
int main()
{cin >> s;int right=0;int left=0;int ret=N;while(right<s.size()){mp[s[right]]++;if(mp[s[right]]==1){cnt++;}while(cnt==26){ret=min(ret,right-left+1);mp[s[left]]--;if(mp[s[left]]==0){cnt--;}left++;}right++;}cout << ret << endl;return 0;
}
4.
#include <iostream>
using namespace std;
const int N=1e5+10;
int n,sum;
int arr[N];
int main()
{cin >> n;for(int i=1;i<=n;i++){cin >> arr[i];sum+=arr[i];}int left=1;int right=1;int ret=0,k=0;while(right<=n){k+=arr[right];while(2*k>=sum){ret=max(ret,sum-k);k-=arr[left];left++;}ret=max(ret,k);right++;}cout << ret << endl;return 0;
}