leetcode刷题之判断链表是否是回文链表

最近在刷leetcode的题目,遇到了一个题目,百思不得其解,后来终于明白,因此写篇博客记录一下。
首先题目是这样的:
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
即给定一个链表,判断链表是否是回环链表。链表的每个节点都存有一个值,如-1 > 1 >1 >-1,即为回文链表。难点在于时间复杂度为O(n),空间复杂度为O(1).
    
 解题思路如下:
1 首先用一个快指针,一个慢指针来遍历链表。快指针每次走两步,慢指针每次走一步。等到快指针遍历完链表,慢指针就正好停留在链表的中央。
2 将链表的后半部分进行反转。
3 将链表的前半部分与后半部分逐个比对。若都相同,则为回文链表,否则不是。
链表遍历的时间复杂度大约为 n/2。反转的时间复杂度为n/2。逐个比对的复杂度为n/2,所以总体的时间复杂度为O(n).而其中用于暂存的节点只有两个。因此空间复杂度为O(1)。

代码如下
`
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode * reverse( struct ListNode * head )
{
struct ListNode * p = head ;
struct ListNode * q = NULL;
struct ListNode * r = NULL ;

if( p == NULL )
    return head ;
else
    q = p->next ;
if( q== NULL )
    return head ;

while( q != NULL )
{
    r = q->next ;
    q->next = p ;
    p = q ;
    q = r ;
}
head->next = NULL ;
head = p ;
return head ;

}
bool isPalindrome(struct ListNode* head) {
struct ListNode * slow = head ;
struct ListNode * fast = head;

if ( ( fast == NULL ) || ( fast->next == NULL ))
    return true ;  
while( ( fast->next != NULL )&&( fast->next->next != NULL ))
{
    slow = slow->next ;
    fast = fast->next->next ;
}
fast = reverse( slow->next ) ;
slow->next = NULL;
while( ( head != NULL ) && ( fast != NULL ) )
{
    if( head->val != fast->val )
        return false ;
    else
    {
        head = head->next ;
        fast = fast->next ;
    }
}

return true ;

}
`

你可能感兴趣的:(算法)