leetcode-234-Palindrome Linked List

Description:

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?
题意:给一个单链表,判断给的数链是不是回文,最好保证O(n)的时间复杂度和O(1)的空间复杂度
C:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* reverseList(struct ListNode* l) {
    struct ListNode* pre = NULL;
    truct ListNode* temp = l;
    while(l!=NULL) {
        temp = l->next;
        l->next = pre;
        pre = l;
        l = temp;
    }
    return pre;
}

bool isPalindrome(struct ListNode* head) {
    if(head == NULL) {
        return true;
    }
    if(head->next == NULL) {
        return true;
    }
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast->next!=NULL && fast->next->next!=NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }
    slow->next = reverseList(slow->next);
    slow = slow->next;
    while(slow!=NULL) {
        if(slow->val != head->val) {
            return false;
        }
        slow = slow->next;
        head = head->next;
    }
    return true;
}

分析:
比如:12321是回文,1221是回文。但是给的是一个单链表,没法从后往前遍历,自然而然地想到了链表反转。我最初的想法是得到前后两个子链表,把后面一个反转,然后做一个遍历就可以判断是不是回文。但是,实施的过程中没处理好,造成了内存泄漏AC不过。
看了一下discussion,确实可以不需要断成两个子链。
步骤:

  • 找到位于中间的那个指针mid,代码中用到了一个比较实用的方法,用slow和fast两个指针往后遍历,fast跳着前进,停止的时候slow就是中间指针,这个方法可以学下来。
  • 找到中间指针之后(这里的中间指针是12321中的3或者是1221中的2),我们把中间指针后面的子链反转一下,所以要写一个reverseList函数完成反转的工作。比如12321现在变成了12312
  • 做完这些,就可以进行遍历比较了。此时mid还是指向12312中的,或者1221中的2,我们让它成为后段子链的开头(mid=mid->next),然后慢慢往后遍历并进行比较判断,以mid==NULL为截止。

END

你可能感兴趣的:(leetcode-234-Palindrome Linked List)