【力扣】回文链表

 🔥博客主页: 我要成为C++领域大神

🎥系列专栏【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】

❤️感谢大家点赞👍收藏⭐评论✍️

本博客致力于分享知识,欢迎大家共同学习和交流。

10f3f804036d438784915f2c6f94fb5d.gif

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

示例 1:

 

fdafeed49bbcf501b5f29b428ec65114.png

输入:head = [1,2,2,1]
输出:true

示例 2:

 

d18260c03019997247111a5878541b70.png

输入:head = [1,2]
输出:false

方法一:双端队列比较首尾

流程:

1、创建一个deque类型的容器,将链表节点元素值依次入队
2、比较队列首尾元素值是否相同
①相同,首尾出队,继续比较
②不相同,不是回文链表,返回false
3、若循环正常结束,队列为空,是回文链表,返回true

代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        deque<int> d;
        while (head != nullptr) {
            d.push_back(head->val);
            head = head->next;
        }

        while (d.size() > 1) { // 只有剩余一个或零个元素时停止循环
            if (d.front() != d.back()) {
                return false;
            }
            d.pop_front();
            d.pop_back();
        }
        return true;
    }
};

方法二:折半拆分逐个比较

流程:

1、将链表从中间节点断开
2、对后一半的链表进行翻转
3、比较两个链表是否相同

代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head == nullptr ) return true;
         ListNode *mid=FindMid(head);  
        ListNode *L1=head;
        ListNode *L2=mid->next;
        L2=reverseList(L2);
        return isSame(L1,L2);
    }
private:
    bool isSame(ListNode *headA,ListNode *headB){
        ListNode *p1=headA;
        ListNode *p2=headB;
        while(p2!=nullptr){
            if(p1->val!=p2->val)
            return false;
            p1=p1->next;
            p2=p2->next;
        }
        return true;
    }
    ListNode* reverseList(ListNode* head) {
        if(head==nullptr) return nullptr;
        ListNode *p1=nullptr;
        ListNode *p2=head;
        ListNode *p3=head->next;
        while(p3){
            p2->next=p1;
            p1=p2;
            p2=p3;
            p3=p3->next;
        }
        p2->next=p1;
        return p2;
    }
    ListNode *FindMid(ListNode *head){
        ListNode *pFast=head;
        ListNode *pSlow=head;
        while(pFast->next && pFast->next->next){
            pFast=pFast->next->next;
            pSlow=pSlow->next;
        }
        return pSlow;
    }
};

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值