我自己第一个写的代码:
bool isPalindrome(struct ListNode* head){
struct ListNode* tail = NULL;
struct ListNode* pos = NULL;
if( head->next == NULL)
{
return true;
}
while( 1 )
{
if( head->next == NULL || (head->next->next == NULL && head->val==head->next->val) )
{
return true;
}
for( tail = head ; tail->next->next != NULL ; tail = tail->next);
if( head->val != tail->next->val)
return false;
if( head->next == NULL || head->next->next == NULL )
{
return true;
}
pos = head;
head = head->next;
tail->next = NULL;
pos->next = NULL;
}
}
1 2 3 2 1
比较第一个数和最后一个数,注意不要把指针放在最后,因为要将最后的链点删除,则考虑倒数第二个链点,并且if条件判断要放在两处,为了防止对空指针解引用
但此时时间复杂度过高O(n) 循环内的代码均要执行一遍,导致超时
算法:首先将链表分成两节,将后一节的链表翻转,在一一比较
1 2 3 3 2 1
1 2 3 || 3 2 1
1 2 3 || 1 2 3
struct ListNode* rollback( struct ListNode* head )
{
struct ListNode* pos = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* p1 = head;
struct ListNode* p2 = head->next;
while( p2 != NULL )
{
p1->next = p2->next;
p2->next = pos->next;
pos->next = p2;
p2 = p1->next;
}
return pos->next;
}
struct ListNode* get_listnode(struct ListNode* head)
{
struct ListNode* fast = head->next;
struct ListNode* slow = head;
struct ListNode* arr = NULL;
while( fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
arr = slow->next;
slow->next = NULL;
return arr;
}
bool isPalindrome(struct ListNode* head){
struct ListNode* mid_listnode = NULL;
struct ListNode* tail = NULL;
if( head == NULL )
{
return true;
}
mid_listnode = get_listnode(head);
tail = rollback(mid_listnode);
while( tail != NULL )
{
if( head->val != tail->val )
{
return false;
}
tail = tail->next;
head = head->next;
} 这里的比较执行n/2次
return true;
}
时间复杂度分析:rollback函数内的语句执行n/2次
get_listnode函数内的语句执行n/2次
T = O(n)
空间复杂度:O(1)