【真题算法·第四期】双指针技术

四季读书网 2 0
【真题算法·第四期】双指针技术

双指针技术(Two Pointers)

【真题算法·第四期】

用两个指针在数组上一次遍历,替代双层循环的 O(n²) 暴力枚举——这是算法优化中最优雅的思维跃迁之一。

📖 一、知识点详解

1. 什么是双指针?

如果擂台法是关注一个变量的变化,那么双指针是关注两个变量的协同配合

擂台法用一个指针(索引)遍历,用另一个变量记录当前最优值;而双指针用两个指针(索引)同时在数据结构上移动,相互配合

双指针(Two Pointers)是一种在数组或字符串中使用两个指针(索引)协同工作的算法技巧。两个指针按一定规则移动,在一次遍历中完成判断或计算。

擂台法: 一个指针遍历 + 一个变量记录最优

双指针(反向): 一个指针从左向右 + 一个指针从右向左

双指针(同向): 一个指针指向起点 + 一个指针向前探索

2. 三种经典模式

模式一相向双指针(左右夹逼)

两个指针从两端向中间移动,常见于判断回文、对称性等。

# 判断字符串是否对称(回文)

i, j = 0, len(s) - 1

while i < j:

    if s[i] != s[j]:

        return False

    i += 1

    j -= 1

return True

【真题算法·第四期】双指针技术-第1张图片-四季读书网

模式二同向快慢双指针

两个指针同向移动,一个快一个慢。常见于去重、滑动窗口预处理等。

# 去重:慢指针 i 指向已处理区域末尾,快指针 j 扫描

i = 0

for j in range(1, n):

    if a[j] != a[i]:

        i += 1

        a[i] = a[j]

return i + 1 # 去重后长度

【真题算法·第四期】双指针技术-第2张图片-四季读书网

模式三两端交替双指针

两个指针从两端交替选取,常见于擂台法同时求最大值和最小值。

i, j = 0, n - 1

while i <= j:

    if a[i] > a[j]:

        # 处理 a[i](较大者)和 a[j](较小者)

    else:

        # 处理 a[j](较大者)和 a[i](较小者)

    i += 1

    j -= 1

【真题算法·第四期】双指针技术-第3张图片-四季读书网

3. 双指针 vs 双层循环

核心区别:双指针不检查所有组合,而是利用「指针移动规则」跳过不可能的情况。

双层循环
双指针
时间复杂度
O(n²)
O(n)
空间复杂度
O(1)
O(1)
本质
所有组合都检查
利用有序性或对称性跳过无效组合

二、复杂算法的基石

双指针本身是一种基础技巧,许多更复杂的算法都建立在它的思想之上:

算法
双指针的角色
指针移动方式
快速排序
分区操作:左右指针向中间交换
相向双指针
归并排序(合并阶段)
合并两个有序数组
同向双指针
二分查找
左右边界向目标位置逼近
相向双指针
滑动窗口
窗口左右边界扩展/收缩
同向双指针
链表环检测(Floyd)
快慢指针步长不同
快慢双指针
三数之和
固定一个数后,左右指针夹逼
固定 + 相向双指针
接雨水
左右边界交替收缩,维护两侧最高
相向双指针
KMP 字符串匹配
模式串自身的前后缀匹配
同向双指针

💡 规律:当一个算法需要两个索引协同移动时,本质上就是双指针思想的延伸。区别仅在于指针的移动规则和步长不同。

◆ ◆ ◆

🧪 二、真题举例

2016年01月选择题第11题:对称字符串

来源:[[201610-Q11-双指针]]

对称字符串的特征是从左到右读和从右到左读完全一样的。如 "abba" 是对称的,"abcba" 也是对称的。判断字符串是否对称的 Python 程序段如下:

s = input()

n = len(s)

k = 0

j = n - 1

for i in range(n // 2):

    # 加框处

if k == 0:

    print("对称")

else:

    print("不对称")

方框中的代码由以下三部分组成:

① j = j - 1

② if c1 != c2: k += 1

③ c1 = s[i]; c2 = s[j]

代码顺序正确的选项是( )

A.①③②   B.②③①   C.③②①   D.②①③

📝 解析

答案:C。先取第 i 个和第 j 个字符 → 比较是否不等 → j 向左移一位。顺序为 ③②①

● ● ●

2024年01月选择题第11题:字符串处理

来源:[[202401-Q11-双指针-数组操作-字符串处理]]

若字符串 s 的值为 "abcde",执行如下程序段后,变量 res 的值不可能是

from random import randint

s = "abcde"

res = ""

i, j = 0, len(s)-1

while i < len(s) and j >= i:

    if randint(0, 1) == 0:

        res += s[i]

        i += 1

    else:

        res += s[j]

        j -= 1

A. "abced"
B. "aecbd"
C. "aedbc"
D. "edcba"

📝 解析

本题考查随机数、逻辑判断、字符串及双指针。
根据代码可知,指针 i 和 j 分别指向字符串 s 的首尾两端。若随机数是 0,则从头部 i 位置取字符 s[i] 正向连接到 res 中;若随机数为 1,则从尾部 j 位置取字符 s[j] 正向连接到 res 中。由于指针 i、j 的步长都为 1,因此取字符时都是逐个变化的,不可能跳跃
选项 A 正确:随机值分别为 00010 或 00011 即可得到。
选项 B 错误:当连接完 ae 后必然连接 b 或 d,不可能跳到 c。
选项 C 正确:随机值分别为 01100 或 01101 即可得到。
选项 D 正确:随机值分别为 11111 或 11110 即可得到。
答案:B。

● ● ●

2021年01月非选择题第15题:双人组队挑选算法

来源:[[202101-Q15-双指针]]

根据申请人的 QA 和 QB 值,从 m 个申请人中挑选 2 人组队参加某挑战赛。条件一是 2 人的 QA 值都必须大于指定参数 h;条件二是 2 人的 QA 值之差(较大值减较小值)小于 h。在满足上述两个条件的所有 2 人组合中,挑选 QB 值之和最大的一个组合。程序运行如下图所示:

【真题算法·第四期】双指针技术-第4张图片-四季读书网

(1)完善划线处代码。
(2)加框处代码有误,请修正。

idh = [6,1,11,2,4,20,7,13]

qa = [175,138,96,78,76,53,46,38] # QA值

qb = [15,26,41,38,30,27,31,29] # QB值

h = int(input("输入参数h:"))

m = len(idh)

n = m

# 按QA降序排序,筛选QA>h

for i in range(m - 1):

    k = i

    for j in range(i + 1, m):

        if qa[j] > qa[k]:

            k = j

    if qa[i] > h: # (2)加框处:qa[i] > h

        if k != i:

            qa[i], qa[k] = qa[k], qa[i]

            qb[i], qb[k] = qb[k], qb[i]

            idh[i], idh[k] = idh[k], idh[i]

    else:

        ___①___

        break

max_sum = 0

s = "没有满足条件的组合"

# 查找符合条件的组合

for i in range(n - 1, 0, -1):

    j = i - 1

    while ___②___:

        if qb[i] + qb[j] > max_sum:

            s = f"组队结果:{idh[i]}号,{idh[j]}号"

            ___③___

        j -= 1

print(s)

📝 解析

(1)① i;② j >= 0 and abs(qa[i] - qa[j]) < h;③ max_sum = qb[i] + qb[j]
(2)原加框处 qa(i) > h 改正:qa[k] > h

◆ ◆ ◆

💡 三、解题要点

1先确定模式

拿到题先判断是相向、同向快慢还是两端交替,不同模式指针移动规则完全不同。

2指针初始位置

相向(i=0, j=n-1)、快慢(i=0, j=0或1)、交替(i=0, j=n-1)——初始值定错全盘皆错。

3移动条件

指针何时移动、每次移动多少,是决定算法正确性的关键。

4终止条件

i < j(相向)、j < n(快慢扫描完)、i <= j(交替)——少一个边界就多一次错误循环。

5避免越界

指针移出数组范围是最常见的 bug,始终检查 i >= 0 和 j < n。

双指针本质:用空间换时间的反面——不增加空间,而是利用数据结构的有序性或对称性,通过指针的智能移动来减少不必要的比较。

📌 总结

双指针是算法优化中最常用的技巧之一。掌握相向、同向快慢、两端交替三种模式,理解指针的初始位置、移动条件和终止条件,就能解决大多数双指针题目。更重要的是,许多高级算法(快排、归并、滑动窗口、Floyd 判圈等)本质上都是双指针思想的延伸。

引用题目均来自于gitee真题库:重磅发布 | 浙江省信息科技选考 算法真题题库(2015-2026),正式开源!
其他真题算法专题:
【真题算法·总览】真题算法知识点总览——(2015-2026)浙江技术选考信息技术历年真题
【真题算法·第一期】数组基本操作与遍历
【真题算法·第二期】循环结构与条件分支
【真题算法·第三期】擂台法求最值

如果这篇文章对你有帮助,欢迎 点赞、分享、推荐

抱歉,评论功能暂时关闭!