题目描述:
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例:
- 输入:head = [1,2,2,1]
输出:true - 输入:head = [1,2]
输出:false
解题思路:
将后半部分的链表反转然后和前半部分的链表进行比较,判断是否是回文链表。
对链表分割时先找到中间节点,使用快慢指针的方法。
slow先指向head,fast指向head->next ,slow一次走一步,fast一次走两步。
如果链表是奇数个节点,则slow正好指向中间节点。
如果是偶数个节点,则slow指向前半部分的尾结点。
需要对slow->next进行反转。然后遍历后半部分的链表并判断即可。
注意
后半部分链表的长度一定的长度一定小于前半部分,所以只需要后半部分的指针指向NULL 的时候就可以结束循环了。
//反转链表
struct ListNode *reverseList(struct ListNode *head)
{
if(head == NULL || head->next == NULL)
return head;
struct ListNode *newHead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newHead;
}
bool isPalindrome(struct ListNode* head){
if(head->next == NULL)
return true;
struct ListNode *slow = head;
struct ListNode *fast = head->next;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
//此时,slow指向中间节点的前驱节点
struct ListNode newHead;
newHead.next = reverseList(slow->next);
struct ListNode *p = newHead.next,*q = head;
//判断是否为回文
while(p)
{
if(p->val != q->val)
return false;
p=p->next;
q=q->next;
}
return true;
}```