如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
示例 1:
输入: s = "A man, a plan, a canal: Panama" 输出:true 解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car" 输出:false 解释:"raceacar" 不是回文串。
示例 3:
输入:s = " " 输出:true 解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。 由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105
s
仅由可打印的 ASCII 字符组成
步骤1:问题分析
-
计算问题性质:我们要判断一个字符串是否为回文串。回文串定义为正序和倒序相同的字符串。题目要求我们忽略字母大小写,并排除所有非字母数字字符。
-
输入和输出条件:
- 输入:字符串
s
,由可打印的 ASCII 字符组成。 - 输出:布尔值,如果字符串是回文串则返回
true
,否则返回false
。
- 输入:字符串
-
限制和边界条件:
- 字符串长度范围
1 <= s.length <= 2 * 10^5
,因此需要高效算法来处理长字符串。 - 字符串可能包含空格、标点等非字母数字字符,需要在处理时去除这些字符。
- 考虑特殊情况,如空字符串
" "
,应该返回true
(因为空字符串也是回文)。
- 字符串长度范围
步骤2:算法设计与步骤分解
-
字符预处理:
- 将字符串
s
转换为全小写。 - 使用过滤方法,保留字母和数字字符,移除其他字符。
- 这一步可以利用双指针或正则表达式来简化。
- 将字符串
-
回文判断:
- 将过滤后的字符串看作一个新的字符串
clean_s
。 - 通过双指针法验证
clean_s
是否为回文。- 指定一个指针从头(
left
)向尾部移动,一个指针从尾部(right
)向头部移动。 - 若
clean_s[left] != clean_s[right]
则说明不是回文,返回false
。 - 若所有位置都匹配,返回
true
。
- 指定一个指针从头(
- 将过滤后的字符串看作一个新的字符串
-
时间复杂度分析:
- 字符过滤阶段:O(n),n 为字符串
s
的长度。 - 回文检查阶段:O(n),双指针遍历
clean_s
。 - 总体时间复杂度为 O(n)。
空间复杂度:O(n);需要额外空间存储过滤后的字符串。
- 字符过滤阶段:O(n),n 为字符串
步骤3:C++实现代码
代码说明:
isalnum(c)
判断字符是否是字母或数字。tolower(c)
将字符转为小写。- 双指针
left
和right
用于从两端向中间检查是否为回文。
步骤4:算法优化和效率提升的启发
- 字符过滤与预处理:通过一次遍历即可完成字符过滤和大小写转换,降低了算法复杂度。
- 双指针法:避免了逆序构造,节省了时间和空间资源。
- 性能考虑:算法设计时最大限度地减少了额外内存的占用,并将遍历次数控制在最少的 O(n)。
这种优化方案尤其适用于大型数据集(如社交媒体文本过滤),对提高整体效率有帮助。
步骤5:实际生活中的应用
应用场景:社交媒体内容过滤
在社交媒体平台中,系统需判断内容是否符合特定模式(如检测是否包含侮辱性词语、回文验证等)。例如,在检测重复性或模式性内容时,可以应用此算法判断某些关键内容是否构成回文串或特定形式内容。
实现方法:
- 先将内容预处理(统一大小写,去除无效字符),然后利用回文验证快速识别特定内容。
- 该算法可以嵌入到实时检测服务中,帮助平台自动识别重复性内容,有助于减少服务器的存储和计算成本。