回文字符串是一种特殊的字符串,其特点是正向和反向的读法完全相同。例如:“madam” 和 “level” 是回文,而 “hello” 不是回文。本文将从简单到复杂,系统讲解多种判断回文字符串的方法,并提供对应的代码实现。
一、什么是回文字符串?
回文字符串的定义:
- 字符串从左到右与从右到左的读法一致。
- 可以为空字符串,也可以是单个字符组成的字符串。
示例
字符串 | 是否回文 |
---|---|
"radar" | 是 |
"hello" | 否 |
"A man, a plan, a canal: Panama" | 是 |
二、实现方法
以下为实现回文判断的常见方法,包括基础方法和扩展方法。
2.1 双指针法
原理
- 使用两个指针,一个从左往右,一个从右往左,逐步比较字符。
- 如果所有字符都相等,则字符串是回文。
Java实现
public class PalindromeChecker {
public static boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
String test = "radar";
System.out.println(test + " 是回文? " + isPalindrome(test));
}
}
Python实现
def is_palindrome(s):
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
test = "radar"
print(f"{test} 是回文? {is_palindrome(test)}")
2.2 字符串反转法
原理
- 反转字符串后,判断是否与原字符串相同。
Java实现
public class PalindromeCheckerReverse {
public static boolean isPalindrome(String s) {
String reversed = new StringBuilder(s).reverse().toString();
return s.equals(reversed);
}
public static void main(String[] args) {
String test = "level";
System.out.println(test + " 是回文? " + isPalindrome(test));
}
}
Python实现
def is_palindrome(s):
return s == s[::-1]
test = "level"
print(f"{test} 是回文? {is_palindrome(test)}")
2.3 忽略大小写与非字母字符
原理
- 忽略非字母数字字符(如空格、标点符号)。
- 将所有字符转换为小写后判断。
Java实现
public class PalindromeCheckerAdvanced {
public static boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
left++;
}
while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
right--;
}
if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
String test = "A man, a plan, a canal: Panama";
System.out.println("\"" + test + "\"" + " 是回文? " + isPalindrome(test));
}
}
Python实现
def is_palindrome(s):
filtered = ''.join(char.lower() for char in s if char.isalnum())
return filtered == filtered[::-1]
test = "A man, a plan, a canal: Panama"
print(f"\"{test}\" 是回文? {is_palindrome(test)}")
2.4 栈方法
原理
- 将字符串的前半部分入栈,后半部分与栈顶元素比较。
Java实现
import java.util.Stack;
public class PalindromeCheckerStack {
public static boolean isPalindrome(String s) {
Stack<Character> stack = new Stack<>();
int n = s.length();
for (int i = 0; i < n / 2; i++) {
stack.push(s.charAt(i));
}
for (int i = (n + 1) / 2; i < n; i++) {
if (stack.pop() != s.charAt(i)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
String test = "madam";
System.out.println(test + " 是回文? " + isPalindrome(test));
}
}
Python实现
def is_palindrome(s):
stack = list(s[:len(s)//2])
for char in s[(len(s)+1)//2:]:
if stack.pop() != char:
return False
return True
test = "madam"
print(f"{test} 是回文? {is_palindrome(test)}")
三、扩展应用
3.1 判断数字是否为回文
思路
- 转换数字为字符串后判断。
- 或者通过数学方法反转数字。
Python实现(数学方法)
def is_palindrome_number(n):
if n < 0:
return False
original, reversed_num = n, 0
while n > 0:
reversed_num = reversed_num * 10 + n % 10
n //= 10
return original == reversed_num
test = 121
print(f"{test} 是回文数? {is_palindrome_number(test)}")
3.2 找最长回文子串
思路
- 使用动态规划或中心扩展法找到最长回文子串。
示例
字符串 "babad"
的最长回文子串为 "bab"
或 "aba"
。
四、方法性能对比
方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
---|---|---|---|
双指针法 | O(n) | O(1) | 普通字符串判断 |
字符串反转法 | O(n) | O(n) | 简单直观实现 |
忽略大小写法 | O(n) | O(n) | 涉及特殊字符过滤 |
栈方法 | O(n) | O(n) | 可扩展到复杂结构如链表 |
五、总结
本文详细介绍了判断回文字符串的多种方法,从双指针、字符串反转到栈方法,涵盖了基础实现与复杂场景扩展。不同场景适合不同的方法。
学习建议
- 从基础开始:熟练掌握双指针法的思想。
- 解决实际问题:尝试处理包含大小写或非字母字符的回文判断。
- 扩展到其他场景:如数字回文、最长回文子串等。
通过实践这些方法,你将能够轻松解决各种回文判断问题,并在实际开发中灵活应用。