请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题
方法一:逆置链表
解释:回文结构实际上就是将这个链表反转过来还是与原来相同,所以我们可以将链表先进行反转然后与原链表比较,但是我们这里得与原链表比较所以不能改变原链表的结构,所以我们得开辟O(n)的空间,如果我们想写出的代码更优秀,就使用下面的思路。
ps:方法一代码简单,就不写了。
方法二:逆置一半链表
解释:我们其实发现如果你逆置后一半链表后,他就与前一半链表完全想同了,有了这个思路,我们得先找打链表的中点(使用快慢指针,在博主之前返回链表中间结点的博客中详细解答)。然后从中间开始反转,将中点当作反转后后一部分链表的头,然后与前半部分比较。
链表反转(含递归详解):https://blog.csdn.net/lucky52529/article/details/84672526
struct ListNode* reverseList(struct ListNode* head)
{
if(head == NULL || head -> next == NULL) return head;
struct ListNode* h = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return h;
}
bool isPalindrome(struct ListNode* head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
if(head == NULL || head -> next == NULL) return true;
while(fast!= NULL && fast -> next!= NULL)
{
fast = fast -> next -> next;
slow = slow -> next;
}
slow = reverseList(slow);
while(slow)
{
if(head -> val != slow -> val )
{
return false;
}
head = head -> next;
slow = slow -> next;
}
return true;
}