234. 回文链表

题目描述

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

示例 1:

在这里插入图片描述

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

示例 2:

在这里插入图片描述

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

提示:

  • 链表中节点数目在范围[1, 105]
  • 0 <= Node.val <= 9

**进阶:**你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

解答

/**
 * 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 || head->next == nullptr) return true;
        ListNode *fast = head, *slow = head;
        ListNode *pre = head; // 用于找到slow前面的节点,就是用于获取前半段尾节点

        // 找中点
        while(fast && fast->next)
        {
            pre = slow;
            fast = fast->next->next;
            slow = slow->next;
        }
        pre->next = nullptr; // 分割链表

        // 反转后半段链表
        ListNode *lastHalf = reverseList(slow);
       
        // 后半段反转的链表和前半段链表进行比较
        while(head)
        {
            if(head->val != lastHalf->val) return false;
            head = head->next;
            lastHalf = lastHalf->next;
        }
        return true;
    }

    ListNode* reverseList(ListNode *head){
        ListNode *tmp;
        ListNode *cur = head;
        ListNode *pre = nullptr;
        // 头插颠倒链表
        while(cur)
        {
            tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

你可能感兴趣的:(LeetCode错题集,链表,数据结构)