给你一个单链表的头节点
head
,请你判断该链表是否为回文链表
。如果是,返回true
;否则,返回false
。示例 1:
输入:head = [1,2,2,1] 输出:true示例 2:
输入:head = [1,2] 输出:false
思路:
- 找到前半部分链表的尾节点。
- 反转后半部分链表。
- 判断是否回文。
- 恢复链表。
- 返回结果。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//链表逆序(头插法)
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode* list,*p;
list=(struct ListNode*)malloc(sizeof(struct ListNode));
list->next=NULL;//先建立一个带头结点的单链表
p=head;
struct ListNode* s;
while(p!=NULL)
{
//头插法
s=(struct ListNode*)malloc(sizeof(struct ListNode));
s->val=p->val;
s->next=list->next;
list->next=s;
p=p->next;
}
return list->next;
}
//找到前半部分链表的尾节点
struct ListNode* endOfFirstHalf(struct ListNode* head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
while (fast->next != NULL && fast->next->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
bool isPalindrome(struct ListNode* head) {
if(head==NULL)
{
return true;
}
//找到前半部分链表的尾节点并反转后半部分链表
struct ListNode* firstHalfEnd=endOfFirstHalf(head);
struct ListNode* secondHalfStart=reverseList(firstHalfEnd->next);
//判断是否是回文
struct ListNode* p1=head;
struct ListNode* p2=secondHalfStart;
bool result=true;
while(result &&p2!=NULL)
{
if(p1->val!=p2->val)
{
result=false;
}
p1=p1->next;
p2=p2->next;
}
//还原链表并返回结果
firstHalfEnd->next = reverseList(secondHalfStart);
return result;
}