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

来源:互联网 发布:知乎日本海外球员名单 编辑:程序博客网 时间:2024/06/10 06:34

最近在刷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 ;

}
`

原创粉丝点击