【力扣-算法面试汇总】5、验证回文串(125)

240 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串

  • 示例 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;
    }
};

image.png

【容器属性法】

// 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;
}

image.png

list链表,是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针连接实现的,链表的存储方式并不是连续的内存空间。链表使用起来比较灵活,但是空间和时间的额外开销比较大。