双指针法是最简单可靠的C++回文判断方式,时间复杂度O(n/2)、空间复杂度O(1),通过首尾字符逐对比较实现,兼容C风格字符串和std::string,无需额外内存,且易于扩展忽略大小写或非字母数字字符等逻辑。

直接用双指针比对首尾字符,是最简单可靠的 C++ 回文判断方式,不需要额外空间、不依赖 STL 算法、兼容 C 风格字符串和 std::string。
用双指针遍历首尾字符
核心逻辑是:从字符串两端向中间逐对比较,一旦发现不等就返回 false;走到中间没出错就返回 true。适用于所有可随机访问的字符序列。
- 对
std::string s:用s[i]和s[j]比较,i从0开始,j从s.length() - 1开始 - 对 C 字符串(
const char* s):先用strlen(s)获取长度,再同上操作;注意检查空指针 - 忽略大小写?在比较前统一转小写,比如用
std::tolower(static_cast(c)) - 忽略非字母数字?需跳过非
std::isalnum字符,但要注意std::isalnum对char传参可能有符号扩展问题,应先转unsigned char
避免 std::reverse 创建副本
有人用 std::string rev = s; std::reverse(rev.begin(), rev.end()); return s == rev;,这会多分配一次内存、多拷贝一次数据,时间空间都是 O(n)。双指针是 O(1) 额外空间、O(n/2) 时间,实际快一倍以上,尤其对长字符串明显。
- 如果字符串长度为 100 万,
std::reverse方案要额外分配 100 万字节内存 -
std::string::operator==内部仍是逐字符比对,相当于做两次遍历 - 自定义比较逻辑(如忽略空格)时,
std::reverse更难适配
处理边界情况:空串、单字符、含 \0 的 string_view
std::string 本身不会含内部 ,但 std::string 本身不会含内部 \0,但 std::string_view 或 C 字符串可能被截断。回文判断必须基于「有效长度」,而非遇到第一个 \0 就停。std::string_view 或 C 字符串可能被截断。回文判断必须基于「有效长度」,而非遇到第一个 就停。std::string 本身不会含内部 \0,但 std::string_view 或 C 字符串可能被截断。回文判断必须基于「有效长度」,而非遇到第一个 \0 就停。
立即学习“C++免费学习笔记(深入)”;
- 空字符串
""是回文,单字符(如"a")也是回文,双指针循环条件应为i ,自然涵盖这两种情况 - 若输入是
std::string_view sv,直接用sv.size()和sv[i],无需担心\0 - 若输入是
const char* s且可能含内部\0,就不能用strlen,必须由调用方传入明确长度
真正容易出错的地方不是算法本身,而是字符处理细节:大小写转换漏了 static_cast 导致 std::tolower 行为未定义,或者用 strlen 处理带内嵌 \0 的缓冲区。这些地方不报错,但结果随机出错。











