题目描述

:::fold-green 相关原题

LeetCode 原题: ✅ 125. 验证回文串

LeetCode 原题忽略大小写和非字母数字字符,输入为 ASCII 字符串;本文按 Unicode 码点比较,保留大小写、空格和标点。

:::

给你一个字符串 s,请判断它的字符正序与倒序是否完全一致,并返回布尔值。

比较以 Unicode 码点为单位,大小写、空格和标点都参与比较,不能忽略或转换这些字符。空字符串返回 true。

示例 1:

输入: s = "Aa"
输出: false
解释: 大小写参与比较,A 与 a 不相同。

示例 2:

输入: s = "a,b,a"
输出: true
解释: 字符从两端向中间逐一对应,逗号也参与比较。

示例 3:

输入: s = "😀a😀"
输出: true
解释: 两端都是同一个 Unicode 码点,中间字符为 a。

提示:

  • 按 Unicode 码点逐一比较,大小写、空格和标点均参与。
  • 空串返回 true。
  • Go 输入约定为合法 UTF-8。

题意分析

本题不做字符过滤或大小写归一化,所有码点都要成对相等。需要注意编码长度与字符数量不同:一个码点可能占多个 UTF-8 字节或两个 UTF-16 单元,不能直接逐字节反转比较。

解法:双指针按 Unicode 码点比较

核心思路

[!blue]

维护尚未比较的半开区间 [left,right)。分别读取左端的下一个码点、右端之前的最后一个码点;不相等就已有一对对称字符冲突,可以立即返回 false。

两端相等时,按各自实际编码宽度推进边界。Java 用 codePointAt、codePointBefore 读取并用 charCount 移动;Go 从 UTF-8 两端解码,使用返回的字节数移动,始终让边界落在码点之间。

区间外的对称位置已经全部相等。当边界相遇或交错,剩余至多一个中间码点,不会产生冲突,返回 true;空串也自然满足这一条件。

解题步骤

  1. 左端指向字符串开头,右端指向字符串末尾之后。
  2. 分别解码两端码点并比较,不同立即返回 false。
  3. 按各自编码宽度推进两端,直到相遇或交错后返回 true。

代码实现

class Solution {
    public boolean exactPalindrome(String s) {
        int left = 0;
        int right = s.length();

        while (left < right) {
            int a = s.codePointAt(left);
            int b = s.codePointBefore(right);

            if (a != b) {
                return false;
            }

            left += Character.charCount(a);
            right -= Character.charCount(b);
        }

        return true;
    }
}
import "unicode/utf8"

func exactPalindrome(s string) bool {
    left, right := 0, len(s)
    for left < right {
        a, na := utf8.DecodeRuneInString(s[left:right])
        b, nb := utf8.DecodeLastRuneInString(s[left:right])
        if a != b {
            return false
        }
        left += na
        right -= nb
    }
    return true
}

复杂度分析

  • 时间复杂度:$O(n)$。
  • 空间复杂度:额外空间 $O(1)$。

关键点总结

[!green]

比较单位是码点,指针移动单位却是 UTF-16 单元或 UTF-8 字节;每次必须按实际编码宽度移动。

易错点总结

[!yellow]

不能删掉标点、空格或转成小写;Go输入约定为合法UTF-8。

相似题目

题目 难度 关联与区别
125. 验证回文串 简单 本题保留大小写、空格和标点,不能复用原题过滤字符与转小写的步骤。
680. 验证回文串 II 简单 允许删除一个字符时,失配处分成跳过左端或右端两个回文检查,复用两端比较过程。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/90633210
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!