给定一个字符串,如何判断这个字符串是否是回文串?
思路一:直接在字符串的首尾两端各放置一个指针*front和*back,然后开始遍历整个字符串,当*front不再小于*back时完成遍历。在此过程中,如果出现二者的值不相等,那么久表示不是回文串;如果两个指针指向的字符始终相等就表示该字符串是回文字符串。
时间复杂度:O(n)
思路二:先使用快慢指针确定出字符串的中间位置,然后分别使用两个指针从开中间位置开始向相反的方向扫描,知道遍历完整个字符串。
时间复杂度:O(n)
找中间位置的方法:
1、快慢指针;
2、一种有效的计算方法
//m定位到字符串的中间位置
int m = ((n >> 1) - 1) >= 0 ? (n >> 1) - 1 : 0;
first = str + m;
second= str + n - 1 - m;
两种思路的代码如下:
//思路一
#include <iostream>
using namespace std;
//*s为字符串,n为字符串的长度
bool IsPalindrome(char *str, int n)
{
//指向字符串首尾的指针
char *front = str;
char *back = str + n - 1;
if(str==NULL||n<1)
{
return false;
}
while (front<back)
{
if (*front != *back)
{
return false;
}
front++;
back--;
}
return true;
}
int main( )
{
char str[] = "abba";
int n = strlen(str);
bool sign;
sign = IsPalindrome(str, n);
if (sign == true)
{
cout << "此字符串是回文字符串"<<endl;
}
else
{
cout << "此字符串不是回文字符串" << endl;
}
return 0;
}
//思路二
#include <iostream>
using namespace std;
//*s为字符串,n为字符串的长度
bool IsPalindrome(char *str, int n)
{
//指向字符串首尾的指针
char *first;
char *second;
if (str == NULL || n<1)
{
return false;
}
//m定位到字符串的中间位置
int m = ((n >> 1) - 1) >= 0 ? (n >> 1) - 1 : 0;
first = str + m;
second= str + n - 1 - m;
while (first>str)
{
if (*first!= *second)
{
return false;
}
first--;
second++;
}
return true;
}
int main( )
{
char str[] = "abcgba";
int n = strlen(str);
bool sign;
sign = IsPalindrome(str, n);
if (sign == true)
{
cout << "此字符串是回文字符串"<<endl;
}
else
{
cout << "此字符串不是回文字符串" << endl;
}
return 0;
}
综上所述,虽然上面两种方法采用不同的遍历方式来扫描字符串,但是最终的时间复杂度都是一样,效率基本上是一样的。