解法一:
一次遍历,装入vector,然后再一次遍历判断回文。
时间复杂度O(n),空间复杂度O(n)
解法二:
找到链表中点,拆分后,逆转后半个链表,然后两个链表同时顺序遍历一次。
若链表长度为奇数,最末尾的元素可以忽略。
时间复杂度O(n),空间复杂度O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int LengthList(struct ListNode* head);
struct ListNode* reverseList(struct ListNode* head);
bool isPalindrome(struct ListNode* head)
{
if(head==NULL||head->next==NULL)
return true;
//旋转后一半。。。但是改变了这个数据的结构...?
int length=LengthList(head);
int mid=(length+1)/2;
struct ListNode* pCurrlent=head; //O(1)
for (int i=0;i<mid;i++)
{
pCurrlent=pCurrlent->next;
}
//最后一个为中点那个
struct ListNode* newMidHead=reverseList(pCurrlent);
pCurrlent=head;
struct ListNode* pCurrlentMid=newMidHead;
for (int i=0;i<(length/2);i++)
{
if (pCurrlent->val!=pCurrlentMid->val)
{
return false;
}
pCurrlent=pCurrlent->next;
pCurrlentMid=pCurrlentMid->next;
}
return true;
}
int LengthList(struct ListNode* head)
{
if(head==NULL)
return 0;
int length=0;
struct ListNode* pCurrent=head;
while(pCurrent!=NULL)
{
length++;
pCurrent=pCurrent->next;
}
//free(pCurrent);
return length;
}
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* newhead;
newhead=NULL;
//这样就不需要翻转了
if (head==NULL||head->next==NULL)
{
return head;
}
struct ListNode* pCurrent=head; //一样的点
while(pCurrent!=NULL)
{
struct ListNode* tmp=pCurrent;
pCurrent=pCurrent->next;
tmp->next=newhead; //把节点放在节点前面,插入到链表的最前端
newhead=tmp;
}
return newhead;
}