开发者

C++实现回文串判断的两种高效方法

开发者 https://www.devze.com 2025-04-11 10:49 出处:网络 作者: 倔强的石头_
目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、解法二:直接原地筛选判断思路代码实现代码解释复杂度分析总结一、问题描述
目录
  • 一、问题描述
    • 示例
  • 二、解法一:将字母数字连接到新的 string
    • 思路
    • 代码实现
    • 代码解释
    • 复杂度分析
  • 三、解法二:直接原地筛选判断
    • 思路
    • 代码实现
    • 代码解释
    • 复杂度分析
  • 总结

    一、问题描述

    在字符串处理中,判断一个字符串是否为回文串是一个经典问题。

    本题有特殊要求:在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,如果短语正着读和反着读都一样,则认为该短语是一个回文串。字母和数字都属于字母数字字符。

    示例

    • 输入: s = "A man, a plan, a canal: Panama",输出:true,解释:处理后得到 "amanaplanacanalpanama" 是回文串。
    • 输入:s = "race a car",输出:false,解释:处理后得到 "raceacar" 不是回文串。
    • 输入:s = " ",输出:true,解释:移除非字母数字字符后,s 是一个空字符串 "",空字符串正着反着读都一样,所以是回文串。

     原题链接 

    125. 验证回文串 - 力扣(LeetCode)

    C++实现回文串判断的两种高效方法

    二、解法一:将字母数字连接到新的 string

    思路

    这种方法的核心思想是先遍历原字符串,把其中的字母数字字符提取出来,同时将大写字母转换为小写字母,存储到一个新的字符串 tmp 中

    然后再对新字符串 tmp 进行回文判断

    代码实现

    #include <IOStream>
    #include <string>
     
    class Solution {
    public:
        bool isPalindrome(string s) //第一种方式 将字母数字连接到新的string
        {
            string tmp;
            string::iterator left = s.begin();
            string::iterator right = s.end();
     
            while (left != right)//第一次遍历,所有字母数字转入新string,并且统一为小写
            {
                if ((*left >= '0' && *left <= '9') || (*left >= 'a' && *left <= 'z'))
                    tmp += *left;
                if (*left >= 'A' && *left <= 'Z')
                    tmp += (*left + 32);
                ++left;
            }
     
            if (tmp.empty())//如果新string为空,则判定为回文串
                return true;
     
            left = tmp.begin();
            right = tmp.end() - 1;
            while (left <= right)//第二次遍历 左右迭代器逐个对比
            {
                if (*left == *right)
                {
                    ++left;
                    --right;
                }
                else
                    return false;
            }
            return true;
        }
    };

    代码解释

    1. 提取字母数字并转换大小写
      • 定义一个空字符串 tmp 用于存储处理后的字符。
      • 使用迭代器 left 遍历原字符串 s,当遇到数字('0' 到 '9')或小写字母('a' 到 'z')时,直接添加到 tmp 中;当遇到大写字母('A' 到 'Z')时,将其 ASCII 码值加 32 转换为小写字母后添加到 tmp 中。
    2. 处理空字符串情况:如果 tmp 为空字符串,根据题目定义,空字符串是回文串,直接返回 true
    3. 回文判断:使用双指针法,left 指向 tmp 的开头,right 指android向 tmp 的结尾,逐个比较对应位置的字符。如果不相等,返回 false;如果都相等,最终返回 true

    复杂度分析

    • 时间复杂度:O(n)需要遍历原字符串一次,再遍历新字符串一次。
    • 空间复杂度:O (n),其中  n是处理后新字符串的长度。

    三、解法二:直接原地筛选判断

    思路

    这种方法不创建新的字符串,而是直接在原字符串上使用双指针法进行筛选和判断。通过两个指针 left 和 right 分别从字符串的两端开始向中间移动,跳过非字母数字字符,同时将字符转换为小写后进行比较。

    代码实现

    #include <iostream>
    #include <string>
    #include &http://www.devze.comlt;cctype>
     
    class Solution {
    public:
        bool isPalindrome(std::string s) //第二种方式,直接原地筛选判断
        {
            string::iterator left = s.begin();
            string::iterator right = s.end() - 1;
     
            while (left < right)
            {
                // 跳过左边的非字母数字字符
                while (left < right && !isalnum(*left))
                {
                    ++left;
                }
                // 跳过右边的非字母数字字符
                while (left < right && !isalnum(*right))
                {
                    --right;
                }
     
                if (left < right) {
                    // 将字符转换为小写后比较
                    if (tolower(*left) != tolower(*right))
                    {
                        return false;
                    }
     编程               ++left;
                    --right;
                }
            }
            //跳出循环,要么left==right,要么left>right 
            //说明所有需要比较的字符对都已经检查过,且都相等
            return true;
        }
    };

    代码解释

    1. 初始化指针:使用迭代器 left 指向字符串的开头,right 指向字符串的结尾。
    2. 跳过非字母数字字符:通过两个内层 while 循编程环,分别将 left 和 right 指针移动到字母数字字符的位置。
    3. 字符比较:将 left 和 right 指针指向的字符转换为小写后进行比较,如果不相等,返回 false;如果相等,继续移动指针。
    4. 返回结果:当 left 大于等于 right 时,说明所有需要比较的字符对都已经检查过,且都相等,返回 true

    复杂度分析

    • 时间复杂度:O(n),只需要遍历一次字符串。
    • 空间复杂度:O(1),只使用了常数级的额外空间。

    总结

    两种解法都能有效解决回文串判断问题:

    解法一逻辑清晰,易于理解,但需要额外的空间存储处理后的字符串;

    解法二原地操作,空间复杂度更低,更适合处理大规模数据。在实际应用中,可以根据具体需求选择合适的解法。

    以上就是C++实现回文串判断的两种高效方法的详细内容,更多关于C++回文串判断的资料请关注编程客栈(www.devze.com)其它相php关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号