双指针的使用

指针指向同一个序列

最长连续不重复子序列

给定一个长度为 $n$ 的整数序列, 请找出最长的不包含重复的数的连续区间, 输出它的长度

 

双指针的使用

指针 $i$ 遍历整个序列,  $j$为当前以 $i$ 为结尾的不产生重复的数的序列的左端点最远能到哪里

可以开一 $cnt$ 数组记录在 $j$ ~ $i$ 序列中出现的字符个数, 当个数 $\leq1$ 时为一种方案

否则指针 $j$ 一直往右走, 直到 $cnt[i] <= 1$, 统计后取 $max$ 即所求

for(int i = 0, j = 0; i < n; i++) {
    cnt[a[i]]++;    //i每轮前进入窗口, 数量++
    while(cnt[a[i]] > 1) cnt[a[j]--, j++;   //j往前推, 直到新来的数的个数 <= 1(j == i时一定满足, 无需额外判断)
    ans = max(ans, i - j + 1);
}

 

 

指针指向两个序列

数组元素的目标和

给定两个升序排序的有序数组 $A$ 和 $B$, 以及一个目标值 $x$, 数组下标从0开始, 求出满足 $A[i] + B[j] = x$ 的数对 $(i, j)$

 

双指针的使用

两个序列有序, 可以使用双指针, 一个指向 $A$ 的开头, 一个指向 $B$ 的结尾, 循环其中一个, 当 $A[i] + B[j] > x$ 时候, 另一个向中间缩直到 $\leq x$ 为止, 最终每轮判断 $\leq$ 是否取等即可

for(int i = 0, j = m - 1; i < n; i++) {
    while(a[i] + b[j] > x) j--;     //当A[i] + B[j] > x时候, 另一个向中间缩直到 <= x
    if(a[i] + b[j] == x) {          //每轮判断 <= 是否取等
        cout << i << ' ' << j;
        break;
    }
}

 

 

使用总结

找到某种类似单调性的性质, 使得两个指针在移动的时候不往回退, 从而优化一重循环

posted @ 2020-10-07 11:52  yikanji  阅读(275)  评论(0)    收藏  举报