[LintCode] Valid Palindrome 验证回文字符串

判断回文字符串
本文介绍了一种算法,用于判断一个字符串是否为回文,只考虑字母数字字符并忽略大小写。提供了两种C++实现方法,均采用双指针策略,分别自定义了辅助函数和使用STL函数。

 

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

Notice

Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

 
Example

"A man, a plan, a canal: Panama" is a palindrome.

"race a car" is not a palindrome.

Challenge

O(n) time without extra memory.

 

LeetCode上的原题,请参见我之前的博客Valid Palindrome

 

解法一:

class Solution {
public:
    /**
     * @param s A string
     * @return Whether the string is a valid palindrome
     */
    bool isPalindrome(string& s) {
        int left = 0, right = s.size() - 1;
        while (left < right) {
            if (!isAlNum(s[left])) ++left;
            else if (!isAlNum(s[right])) --right;
            else if ((s[left] + 32 - 'a') % 32 != (s[right] + 32 - 'a') % 32) return false;
            else {
                ++left; --right;
            }
        }
        return true;
    }
    bool isAlNum(char c) {
        if (c >= 'a' && c <= 'z') return true;
        if (c >= 'A' && c <= 'Z') return true;
        if (c >= '0' && c <= '9') return true;
        return false;
    }
};

 

解法二:

class Solution {
public:
    /**
     * @param s A string
     * @return Whether the string is a valid palindrome
     */
    bool isPalindrome(string& s) {
        int left = 0, right = s.size() - 1;
        while (left < right) {
            if (!isalnum(s[left])) ++left;
            else if (!isalnum(s[right])) --right;
            else if ((s[left] + 32 - 'a') % 32 != (s[right] + 32 - 'a') % 32) return false;
            else {
                ++left; --right;
            }
        }
        return true;
    }
};

 

转载于:https://www.cnblogs.com/grandyang/p/5731347.html

<think>嗯,用户想用Python来验证回文字符串,我需要仔细想想怎么回答这个问题。首先,回文字符串的定义是正读和反读都一样的字符串,比如“level”或者“madam”。那Python里怎么实现呢?常见的思路可能是反转字符串然后比较是否相同。不过用户提供的引用里提到了不同的方法,我需要参考一下。 引用3和引用4中的方法都是先处理字符串,比如转小写、去除非字母数字字符,然后比较反转后的字符串。比如使用string == string[::-1]。这种方法简单直接,应该是最常见的做法。那用户可能需要一个这样的基本实现。 另外,引用5提到的是逐个比较字符的方法,比如比较第i个和倒数第i个字符。这种方法可能更高效,特别是当字符串很长时,可以在发现不匹配时提前终止,不需要反转整个字符串。不过对于大多数情况,直接反转可能更简洁。 用户的需求是编写验证回文的函数,可能需要考虑不同情况,比如是否忽略大小写、空格和标点符号。根据引用中的例子,处理字符串的步骤包括转换为小写、去除非字母数字字符。所以,在函数中应该包含这些预处理步骤。 比如,用户给出的例子"A man, a plan, a canal: Panama",处理后会变成"amanaplanacanalpanama",这时候反转比较就容易了。所以,代码中需要用到lower()和isalnum()来处理字符串。 另外,用户可能关心不同方法的优缺点。比如,反转字符串的方法虽然简洁,但会创建新的字符串,可能占用更多内存。而逐个比较的方法则不需要额外空间,但代码稍复杂。可能需要根据具体情况选择合适的方法。 然后,我需要组织回答的结构。先介绍回文的定义,然后给出几种不同的实现方法,每种方法的步骤和代码示例。还要注意代码格式是否正确,比如使用$...$和$$...$$的规则,但这里可能主要是Python代码块。不过根据系统指令,数学表达式需要正确使用LaTeX格式,但代码块可能用三个反引号包裹。 还要生成相关问题,比如如何忽略大小写和标点,不同方法的性能比较,或者如何处理特殊字符等。这样用户可以有进一步的问题参考。 总结步骤应该是: 1. 预处理字符串:转小写,去除非字母数字。 2. 比较处理后的字符串与其反转是否相同。 3. 或者逐个字符比较,减少内存使用。 然后给出对应的代码例子,并说明各自的优缺点。最后生成相关问题。</think>### Python验证回文字符串的实现方法 #### 一、核心实现原理 回文字符串验证需要满足:**处理后的字符串与其反转完全一致**。需先进行数据预处理: 1. 忽略大小写:使用$string.lower()$统一为小写 2. 过滤非字母数字字符:使用$isalnum()$函数筛选有效字符[^4] 3. 判断对称性:比较处理后的字符串与反转字符串是否相同 #### 二、具体实现步骤 ##### 方法1:字符串反转法 ```python def is_palindrome(s: str) -> bool: # 预处理:去除非字母数字字符并转小写 processed_str = ''.join(ch.lower() for ch in s if ch.isalnum()) # 判断是否等于反转字符串 return processed_str == processed_str[::-1] ``` **时间复杂度**:$O(n)$,空间复杂度$O(n)$[^3] ##### 方法2:双指针验证法 ```python def is_palindrome(s: str) -> bool: processed_str = ''.join(ch.lower() for ch in s if ch.isalnum()) left, right = 0, len(processed_str)-1 while left < right: if processed_str[left] != processed_str[right]: return False left += 1 right -= 1 return True ``` **优点**:提前终止无效比较,节省时间[^5] #### 三、关键代码说明 1. `ch.isalnum()`过滤标点符号和空格[^4] 2. `[::-1]`通过切片操作实现字符串反转 3. `lower()`统一字符大小写避免误判 #### 四、测试用例验证 ```python print(is_palindrome("A man, a plan, a canal: Panama")) # True print(is_palindrome("race a car")) # False print(is_palindrome("level")) # True print(is_palindrome("0P")) # False ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值