题目描述:
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
思想:
找到中间的点,然后反转后半部分,前半部分与后半部分此时就是一样的了,只需一个一个对比。要注意链表长度奇偶的问题。
方法一:求长度+链表反转
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//反转链表
static void Inverted(struct ListNode* head)
{
if (head == NULL)
return;
struct ListNode* p = head->next;
struct ListNode* q = p->next;
head->next = NULL;
while (p != NULL)
{
p->next = head->next;
head->next = p;
p = q;
if (q != NULL)
q = q->next;
}
}
//求链表长度
int getLength(struct ListNode* head)
{
if(head==NULL)
return -1;
int count = 0;
struct ListNode*p = head;
while (p!=NULL)
{
count++;
p = p->next;
}
return count;
}
bool isPalindrome(struct ListNode* head)
{
if(head==NULL)
return false;
if(head->next==NULL)
return true;
int len = getLength(head);
struct ListNode*p = head;
struct ListNode*q = head;
if(len%2==0)//偶数长
{
for(int i=0;i<len/2-1;i++)
{
p = p->next;
}
}
else//奇数
{
for(int i=0;i<len/2;i++)
{
p = p->next;
}
}
Inverted(p);
for(int i=0;i<len/2;i++)
{
if(p->next!=NULL&&p->next->val==q->val)
{
p = p->next;
q = q->next;
}
else
break;
}
if(p->next==NULL)
return true;
return false;
}
方法二:快慢指针+链表反转
今天稍微改进了一下
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//反转链表
static void Inverted(struct ListNode* head)
{
if (head == NULL)
return;
struct ListNode* p = head->next;
struct ListNode* q = p->next;
head->next = NULL;
while (p != NULL)
{
p->next = head->next;
head->next = p;
p = q;
if (q != NULL)
q = q->next;
}
}
bool isPalindrome(struct ListNode* head)
{
if(head==NULL)
return false;
if(head->next==NULL)
return true;
struct ListNode*p = head;
struct ListNode*q = head->next->next;
while(q!=NULL)
{
p = p->next;
q = q->next;
if(q==NULL)
break;
q = q->next;
}
Inverted(p);
q = head;
while(p->next!=NULL)
{
if(p->next->val==q->val)
{
p = p->next;
q = q->next;
}
else
break;
}
if(p->next==NULL)
return true;
return false;
}
方法三:顺序栈
先全部入栈,然后出一半与原链表对比。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool isPalindrome(struct ListNode* head){
char s[100001];//空间换时间
int top = 0;//栈顶指针
int len=0;
struct ListNode*p ;
for(p = head;p!=NULL;p = p->next)//入栈
{
s[top++] = p->val;
len++;
}
int i;
for(p = head,i=0;i<len/2;i++,p = p->next)
{
if(p->val!=s[--top])
return false;
}
return true;
}