125. 验证回文串

301 阅读1分钟

题目描述

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。

示例

示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
解释:"amanaplanacanalpanama" 是回文串

示例 2:
输入: "race a car"
输出: false
解释:"raceacar" 不是回文串

提示:
1 <= s.length <= 2 * 105
字符串 s 由 ASCII 字符组成

来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/va…

分析

  1. 根据题目描述,只考虑字母和数字,因此第一步首先将字符串转换成只包含数字和字母的形式
  2. 要找回文字符串,就是第一个字符和最后一个字符相同,第二个字符和倒数第二个字符相同,依次类推,我们可以想到用双指针法,left指针指向首字符,right指针指向尾字符,又根据题目描述忽略大小写,因此我们将字符统一转换成小写进行比较,如果tolower(s[left]) == tolower(s[right]),那么说明left位置和right位置的字符组成回文,比较下一对,left++,right++,依次比较,直到left和right相遇或者遇到不满足回文条件(left和right位置的字符不相同)时退出

例:s="race a car"

  1. 经过处理,将其转换为只包含数字和字母的形式"raceacar",一共8个字符(0~7)
  2. left=0,right=7,tolower(s[left])==r,tolower(s[right])==r,相同,符合回文条件,left++,right--,比较两个值都为a,符合,依次类推,直到left==3,right==4时,tolower(s[left])==e,tolower(s[right])==a,不相等,因此该字符串不符合回文条件

实现

void updateString(char *s, char *pRes, int *pResLen)
{
    while (*s != '\0') {
        if (((*s - '0') >= 0 && (*s - '0') <= 9) || (*s >= 'a' && *s <= 'z') ||
            (*s >= 'A' && *s <= 'Z')) {    // 表明字符是数字或字母,放入pRes中
                *pRes = *s;
                pRes++;
                (*pResLen)++;
        }
        s++;
    }
}

bool isPalindrome(char *s)
{
    int resLen = 0;        // 保存源字符串中去掉非字母与非数字的字符串长度

    // pRes指针后面指向源字符串中去掉非字母与非数字的字符串
    char *pRes = (char*)malloc(sizeof(char) * strlen(s));
    if (strlen(s) <= 1) {    // 如果字符串为空或者只有一个字符,认为是回文字符串
        return true;
    }

    // 给pRes和pResLen赋值
    updateString(s, pRes, &resLen);
    if (resLen <= 1) {
        return true;
    }
    // left和right分别指向字符串两边,向中间夹逼,判断是否回文
    int left = 0;
    int right = resLen - 1;
    while (left < right) {
        if (tolower(pRes[left]) != tolower(pRes[right])) {    // 不是回文
            return false;
        }
        left++;
        right--;
    }
    return true;
}