小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串。
-
示例 1:
输入: "A man, a plan, a canal: Panama" 输出: true 解释:"amanaplanacanalpanama" 是回文串
-
示例 2:
输入: "race a car" 输出: false 解释:"raceacar" 不是回文串
来源:力扣
【双指针法】
// C++
class Solution
{
public:
bool isPalindrome(string s)
{
// 字符串为空时返回true
if (s.empty())
{
return true;
}
// 定义左右指针
int left = 0;
int right = s.size() - 1;
// 左指针小于右指针
while (left <= right)
{
char tmpLeft = s[left];
char tmpRight = s[right];
// 判断左右指针指向的字符是否在[A-Z]之间
// 若在[A-Z]之间,将其转化为小写字母[a-z]
if (tmpLeft >= 'A' && tmpLeft <= 'Z')
{
tmpLeft += 32;
}
if (tmpRight >= 'A' && tmpRight <= 'Z')
{
tmpRight += 32;
}
// 判断左右指针指向的字符是否在[a-z][0-9]之间
if ((tmpLeft >= 'a' && tmpLeft <= 'z') || (tmpLeft >= '0' && tmpLeft <= '9'))
{
// 左右指针指向的字符都在[a-z][0-9]之间,则判断两个字符是否相等
if ((tmpRight >= 'a' && tmpRight <= 'z') || (tmpRight >= '0' && tmpRight <= '9'))
{
// 左右两个字符不相等时,直接返回false
if (tmpLeft != tmpRight)
{
return false;
}
// 相等的话,左右指针分别加减1
left++;
right--;
}
else
{
right--;
}
}
else
{
left++;
}
}
return true;
}
};
【容器属性法】
// C++
// 使用list容器的reverse方法判断字符串是否是回文串
bool isPalindrome2(string s)
{
list<char> L1;
// 将字符转换为小写后添加到list容器中
string::iterator it = s.begin();
while (it != s.end())
{
if (*it >= 'A' && *it <= 'Z')
{
L1.push_back(*it + 32);
}
else if ((*it >= 'a' && *it <= 'z') || (*it >= '0' && *it <= '9'))
{
L1.push_back(*it);
}
it++;
}
// list的拷贝构造函数,将L1的值赋值给L2
list<char> L2(L1);
// 将L2反转
L2.reverse();
// 若L2反转后等于L1,则是回文串
if (L2 == L1)
{
return true;
}
return false;
}
list链表,是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针连接实现的,链表的存储方式并不是连续的内存空间。链表使用起来比较灵活,但是空间和时间的额外开销比较大。