双指针算法
for (int i = 0, j = 0; i < n; i ++ ) { while (j < i && check(i, j)) j ++ ; // 具体问题的逻辑 }
(AcWing yxc模板)
常见问题分类: (1) 对于一个序列,用两个指针维护一段区间 (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
1.常见例题:最长连续不重复子序列
给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。 输入格式 第一行包含整数 n。 第二行包含 n 个整数(均在 0∼105 范围内),表示整数序列。 输出格式 共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。 数据范围 1≤n≤105 输入样例: 5 1 2 2 3 5 输出样例: 3
#include <iostream> using namespace std; const int N = 100010; int n; int q[N], s[N]; int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]); int res = 0; for (int i = 0, j = 0; i < n; i ++ ) { s[q[i]] ++ ; while (j < i && s[q[i]] > 1) s[q[j ++ ]] -- ; res = max(res, i - j + 1); } cout << res << endl; return 0; }
2.三数之和
class Solution { // 并不适合做哈希,因为题目给出要去重,而哈希的话会比较复杂,去重操作不好做 public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> res=new ArrayList<>(); Arrays.sort(nums); for(int i=0;i<nums.length;i++){ if(i>0&&nums[i]==nums[i-1]) continue; int left=i+1,right=nums.length-1; while(left<right){ if(nums[i]+nums[left]+nums[right]>0){ right--; }else if(nums[i]+nums[left]+nums[right]<0){ left++; }else{ List<Integer> part=new ArrayList<>(); part.add(nums[i]); part.add(nums[left]); part.add(nums[right]); res.add(part); //去重 while(left<right&&nums[right]==nums[right-1]) right--; while(left<right&&nums[left]==nums[left+1]) left++; left++; right--; } } } return res; } }
3.四数之和
class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> res=new ArrayList<>(); Arrays.sort(nums); for(int i=0;i<nums.length;i++){ if(i>0&&nums[i]==nums[i-1]) continue; for(int j=i+1;j<nums.length;j++){ if(j>i+1&&nums[j]==nums[j-1]) continue; int l=j+1,r=nums.length-1; while(l<r){ if((long)nums[i]+nums[j]+nums[l]+nums[r]<target){ l++; }else if((long)nums[i]+nums[j]+nums[l]+nums[r]>target){ r--; }else{ List<Integer> part=new ArrayList<>(); part.add(nums[i]); part.add(nums[j]); part.add(nums[l]); part.add(nums[r]); res.add(part); while(l<r&&nums[l]==nums[l+1]) l++; while(l<r&&nums[r]==nums[r-1]) r--; l++;r--; } } } } return res; } }