编程进阶网 编程进阶网
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机组成原理
  • 操作系统原理
  • 网络协议原理
  • 数据库系统原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机组成原理
  • 操作系统原理
  • 网络协议原理
  • 数据库系统原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • 数据结构与算法专栏
  • 数据结构导论

  • 线性结构详解

  • 树哈希结构论

  • 容器设计实战

  • 经典算法思想

  • 工程案例剖析

  • 算法题库精练

    • README
    • 数组算法合集
    • 链表算法合集
    • 栈队算法合集
    • 哈希算法合集
    • 二叉树算法集
    • 堆算法题合集
    • 图算法题合集
    • 二分查找合集
    • 双指针算法集
      • 验证回文串(Valid Palindrome)
        • 01. 题目描述
        • 02. 题目分析
        • 03. 代码
        • 04. 总结
      • 判断子序列(Is Subsequence)
        • 01. 题目描述
        • 02. 题目分析
        • 03. 代码
        • 04. 总结
      • 反转字符串(Reverse String)
        • 01. 题目描述
        • 02. 题目分析
        • 03. 代码
        • 04. 双指针题型速查
        • 05. 总结
      • 平方数之和(Sum of Square Numbers)
        • 01. 题目描述
        • 02. 题目分析
        • 03. 代码
        • 04. 总结
    • 排序算法合集
    • 分治算法合集
    • 贪心算法合集
    • 回溯算法合集
    • 动规算法合集
    • 位运算算法集
    • 数学算法合集
  • 算法
  • 算法题库精练
杨充
2024-06-21
目录

双指针算法集

# 验证回文串(Valid Palindrome)

LeetCode 125 · ⭐ · 双指针

# 01. 题目描述

只考虑字母和数字字符,忽略大小写。判断是否为回文。

示例:

输入:"A man, a plan, a canal: Panama"  → true  ("amanaplanacanalpanama")
输入:"race a car"                       → false

# 02. 题目分析

2.1 双指针夹逼

2.2 技巧

Character.isLetterOrDigit() 只保留字母和数字。Character.toLowerCase() 统一转小写。

# 03. 代码

Java:

public boolean isPalindrome(String s) {
    int l = 0, r = s.length() - 1;
    while (l < r) {
        while (l < r && !Character.isLetterOrDigit(s.charAt(l))) l++;
        while (l < r && !Character.isLetterOrDigit(s.charAt(r))) r--;
        if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r)))
            return false;
        l++; r--;
    }
    return true;
}

Python:

def isPalindrome(self, s: str) -> bool:
    s = ''.join(c.lower() for c in s if c.isalnum())
    return s == s[::-1]

C++:

bool isPalindrome(string s) {
    int l=0, r=s.size()-1;
    while(l<r){ while(l<r&&!isalnum(s[l])) l++; while(l<r&&!isalnum(s[r])) r--; if(tolower(s[l])!=tolower(s[r])) return false; l++; r--; }
    return true;
}

复杂度:O(N)/O(1)。

# 04. 总结

核心技巧 说明
双指针夹逼 两端向中间收缩
过滤非字母数字 isLetterOrDigit / isalnum
忽略大小写 toLowerCase / tolower

相关题目:123 反转字符串

# 判断子序列(Is Subsequence)

LeetCode 392 · ⭐ · 双指针

# 01. 题目描述

判断 s 是否为 t 的子序列(不要求连续,但相对顺序不变)。

示例:

输入:s="abc", t="ahbgdc"    → true
输入:s="axc", t="ahbgdc"    → false

# 02. 题目分析

双指针追及

i 指向 s 中待匹配字符,j 扫描 t。匹配成功时 i 前进,j 一直前进。

进阶:大量 s 查询

如果有 k 个 s 要判断,每次 O(N) 太慢。预处理 t 的字符位置列表,用二分加速到 O(logN)。

# 03. 代码

Java:

public boolean isSubsequence(String s, String t) {
    int i = 0, j = 0;
    while (i < s.length() && j < t.length()) {
        if (s.charAt(i) == t.charAt(j)) i++;
        j++;
    }
    return i == s.length();
}

Python:

def isSubsequence(self, s: str, t: str) -> bool:
    i = 0
    for c in t:
        if i < len(s) and s[i] == c: i += 1
    return i == len(s)

C++:

bool isSubsequence(string s, string t) {
    int i=0;
    for(int j=0;i<s.size()&&j<t.size();j++)
        if(s[i]==t[j]) i++;
    return i==s.size();
}

复杂度:O(N)/O(1)。

# 04. 总结

核心 说明
双指针追及 i 追 s,j 扫 t
关键条件 s[i]==t[j] 匹配成功 i++
进阶 预处理+二分支持多查询

相关题目:121 回文串

# 反转字符串(Reverse String)

LeetCode 344 · ⭐ · 双指针原地交换

# 01. 题目描述

原地反转字符数组。

示例:

输入:['h','e','l','l','o']  →  ['o','l','l','e','h']

# 02. 题目分析

双指针原地交换

# 03. 代码

Java:

public void reverseString(char[] s) {
    for (int l = 0, r = s.length - 1; l < r; l++, r--) {
        char t = s[l]; s[l] = s[r]; s[r] = t;
    }
}

Python:

def reverseString(self, s: List[str]) -> None:
    s.reverse()

C++:

void reverseString(vector<char>& s) {
    for(int l=0,r=s.size()-1;l<r;l++,r--) swap(s[l],s[r]);
}

复杂度:O(N)/O(1)。

# 04. 双指针题型速查

类型 题目 指针移动
两端夹逼 121 回文 / 123 反转 l++, r-- 同步
同向追及 122 子序列 j 始终前进,i 匹配才进
左右夹逼 A005 盛水 / A006 接雨 哪边矮移哪边
平方数 126 平方数之和 l²+r² vs c 决定方向

# 05. 总结

核心启示 说明
原地反转 双指针首尾交换,无需额外空间
双指针本质 用两端向中间的方式将 O(N) 空间降到 O(1)

相关题目:121 回文串、A005 盛水容器

# 平方数之和(Sum of Square Numbers)

LeetCode 633 · ⭐⭐ · 双指针

# 01. 题目描述

判断是否存在整数 a,b 使 a² + b² = c。

示例:

输入:c = 5  → true  (1² + 2² = 5)
输入:c = 3  → false

# 02. 题目分析

2.1 朴素思路

暴力枚举 a ∈ [0, √c],检查 c-a² 是否为完全平方数 → O(√c)。

2.2 双指针优化

与 A005 盛最多水的容器同一框架——用双指针替代暴力枚举的 O(N²)。

2.3 正确性

当 l²+r² < c 时,任何含有当前 l 的组合都不可能等于 c(因为 r 已是最大可能值)→ 放弃 l。

# 03. 代码

Java:

public boolean judgeSquareSum(int c) {
    long l = 0, r = (long) Math.sqrt(c);
    while (l <= r) {
        long sum = l * l + r * r;
        if (sum == c) return true;
        if (sum < c) l++;
        else r--;
    }
    return false;
}

Python:

def judgeSquareSum(self, c: int) -> bool:
    l, r = 0, int(c ** 0.5)
    while l <= r:
        s = l * l + r * r
        if s == c: return True
        if s < c: l += 1
        else: r -= 1
    return False

C++:

bool judgeSquareSum(int c) {
    long l=0, r=sqrt(c);
    while(l<=r){ long s=l*l+r*r; if(s==c) return true; if(s<c) l++; else r--; }
    return false;
}

复杂度:O(√c)/O(1)。

# 04. 总结

核心启示 说明
双指针替代暴力 把 O(N²) 枚举优化为 O(N)
正确性 sum<c → l++ 是安全的(r已达最大)
与盛水容器相似 同一框架:根据 sum 与 target 的关系决定移动方向

相关题目:A005 盛水容器、123 反转字符串

#算法
上次更新: 2026/06/28, 17:55:19
二分查找合集
排序算法合集

← 二分查找合集 排序算法合集→

最近更新
01
科学方法实践论法
06-28
02
辩证思维矛盾论法
06-28
03
毛选中的调查观念
06-28
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 鄂ICP备2024073355号-1 | 鄂ICP备2024073355号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式