(C++)Leetcode狂刷200题——标签“链表篇--简单难度10道 #234. 回文链表

本文介绍两种判断链表是否为回文的有效方法:一是利用栈进行数据存储和比较;二是采用双指针技巧,结合链表反转实现O(n)时间复杂度和O(1)空间复杂度的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
第五道、#234. 回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1、借助栈检查回文链表
(1)将链表里的所有val值入栈操作
(2)然后再从头到尾遍历链表
(3)比较其与栈顶元素是否相等(因为栈的数据结构特征,后来者据上此时比较的元素刚好是链表的首部和尾部比较)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        stack<int> st;    //存储val
        ListNode* p=head;
        while(p){     //存数据入栈
            st.push(p->val);
            p = p->next;
        }
        p = head;
        while(p){  //遍历链表元素
            if(p->val != st.top())  //检测回文性
            return false;
            else{
                p = p->next;  //指向下一个节点
                st.pop();  //出栈
            }
        }
        return true;
    }
};

2、双指针法
(1)分别用快慢指针指向头部
(2)遍历链表,慢指针每次跳到下一个,快指针跳到下一个的下一个
(3)慢指针遍历的时候同时反转链表的转向,方便后面检验回文性
(4)当链表长度为奇数时记得将slow向后跳一个,去除中间项

	/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next)   //!!!!!!!!当链表为空或者只有一个节点时返回真!!!!!
            return 1;         //切忌!!!!!!先考虑特殊情况
        ListNode* slow = head;  //慢指针
        ListNode* fast = head;  //快指针
        ListNode* p = head;    
        ListNode* pre = NULL;

        while(fast && fast->next){
            p = slow;
            slow = slow->next;
            fast = fast->next->next;

            p->next = pre; //反转链表
            pre = p;
        }

        if(fast)   // 如果链表节点为奇数个,跳过中间节点
            slow = slow->next;

        while(p){
            if(p->val != slow->val)  //从中间分别向两边遍历,检验回文性
                return false;
            slow = slow->next;
            p = p->next;
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值