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

2025-03-03 17:50

本文主要是介绍C++实现回文串判断的两种高效方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友...

一、问题描述

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

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

示例

  • 输入: 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.chinasem.cnlt;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++回文串判断的资料请关注China编程(www.chinasem.cn)其它相php关文章!

这篇关于C++实现回文串判断的两种高效方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153620

相关文章

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库