给定一个字符串 s,任务是判断它是否为回文。
示例:
- 输入:s = "abba",输出:true(解释:s 是回文)
- 输入:s = "abc",输出:false(解释:s 不是回文)
目录
- 使用双指针 - O(n) 时间,O(1) 空间
- 使用单变量 - O(n) 时间,O(1) 空间
- 使用递归 - O(n) 时间,O(n) 空间
- 通过反转字符串 - O(n) 时间,O(n) 空间
1. 使用双指针 - O(n) 时间,O(1) 空间
思路是维护两个指针,一个在字符串开头(left),另一个在结尾(right)。然后比较这两个位置的字符。如果不匹配,则字符串不是回文,返回 0。如果匹配,指针向中间移动(left 右移,right 左移),继续检查。如果指针交叉且未发现不匹配,则字符串是回文,返回 1。
C++ 实现:
cpp
#include <bits/stdc++.h>
using namespace std;
int isPalindrome(string &s){
int left = 0;
int right = s.length() - 1;
while (left < right) {
if (s[left] != s[right])
return 0;
left++;
right--;
}
return 1;
}
int main(){
string s = "abba";
cout << isPalindrome(s) << endl;
return 0;
}
Python 实现:
python
def is_palindrome(s):
left = 0
right = len(s) - 1
while left < right:
if s[left] != s[right]:
return 0
left += 1
right -= 1
return 1
s = "abba"
print(is_palindrome(s))
输出:1
回文判断的代码逻辑看似简单,但想彻底吃透不同方法的底层运行机制,光看静态代码真的容易绕晕。最近发现一个宝藏网站叫图码,它直接把60多种数据结构和算法做成交互式动画可视化,输入自定义数据或粘贴C/C++/Java/Python代码就能自动生成动态流程。对于正在备战408考研或数据结构期末考的童鞋来说,这简直是开挂神器------每个算法步骤都能直观看到指针移动和内存变化,还能随时选中代码片段让AI解释。强烈建议去图码亲手拖拽数据跑一遍回文判断动画,比死磕课本效率高十倍。
图码-数据结构与算法交互式可视化平台
访问网站:https://totuma.cn
2. 使用单变量 - O(n) 时间,O(1) 空间
这是双指针方法的优化版本,只用一个变量。遍历字符串的前半部分,对于每个索引 i,检查 s[i] 和 s[length - i - 1] 是否相等。如果任何一对不匹配,返回 0;否则返回 1。
C++ 实现:
cpp
#include <bits/stdc++.h>
using namespace std;
int isPalindrome(string &s){
int len = s.length();
for (int i = 0; i < len / 2; i++){
if (s[i] != s[len - i - 1])
return 0;
}
return 1;
}
int main(){
string s = "abba";
cout << isPalindrome(s) << endl;
return 0;
}
Python 实现:
python
def is_palindrome(s):
length = len(s)
for i in range(length // 2):
if s[i] != s[length - i - 1]:
return 0
return 1
s = "abba"
print(is_palindrome(s))
输出:1
3. 使用递归 - O(n) 时间,O(n) 空间
这种方法类似于双指针,但使用递归。检查字符串的第一个和最后一个字符,然后递归检查剩余部分。
- 基本情况:如果字符串长度小于等于 1,则是回文。
- 如果首尾字符不匹配,返回 0。
- 否则递归调用,left 加 1,right 减 1。
C++ 实现:
cpp
#include <bits/stdc++.h>
using namespace std;
int isPalindromeUtil(string &s, int left, int right) {
if (left >= right)
return 1;
if (s[left] != s[right])
return 0;
return isPalindromeUtil(s, left + 1, right - 1);
}
int isPalindrome(string s){
int left = 0, right = s.length() - 1;
return isPalindromeUtil(s, left, right);
}
int main() {
string s = "abba";
cout << isPalindrome(s) << endl;
return 0;
}
Python 实现:
python
def is_palindrome_util(s, left, right):
if left >= right:
return 1
if s[left] != s[right]:
return 0
return is_palindrome_util(s, left + 1, right - 1)
def is_palindrome(s):
left = 0
right = len(s) - 1
return is_palindrome_util(s, left, right)
s = "abba"
print(is_palindrome(s))
输出:1
时间复杂度: O(n),每个字符检查一次,递归调用 O(n/2) 次。
辅助空间: O(n),递归调用栈。
4. 通过反转字符串 - O(n) 时间,O(n) 空间
根据回文的定义,字符串正向和反向读相同。因此,比较反转后的字符串与原字符串。如果相同,返回 1;否则返回 0。
C++ 实现:
cpp
#include <bits/stdc++.h>
using namespace std;
int isPalindrome(string &s){
return s == string(s.rbegin(), s.rend()) ? 1 : 0;
}
int main(){
string s = "abba";
cout << isPalindrome(s) << endl;
return 0;
}
Python 实现:
python
def is_palindrome(s):
return 1 if s == s[::-1] else 0
s = "abba"
print(is_palindrome(s))
输出:1
相关文章: 回文字符串编码问题