[LeetCode]81. Palindrome Linked List回文链表

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?

 

Subscribe to see which companies asked this question

 
解法1:不考虑Follow中O(1)空间的要求,最简单的方法就是借助一个数组保存链表每个节点的值,然后根据从两头到中间比较数组元素即可。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> elem;
        while (head != NULL) {
            elem.push_back(head->val);
            head = head->next;
        }
        int n = elem.size();
        for (int i = 0; i < n / 2; ++i) {
            if (elem[i] != elem[n - 1 - i])
                return false;
        }
        return true;
    }
};

 

解法2:一个O(1)空间复杂度的笨办法就是先扫描一遍链表,统计节点数目。然后两层循环依次比较对应位置节点值。这样时间复杂度在O(n^2),会超时Time Limit Exceeded

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        int n = 0;
        ListNode* curr = head;
        while (curr != NULL) {
            ++n;
            curr = curr->next;
        }
        int loop = 0;
        ListNode* beg = head;
        while(loop < n / 2) {
            ListNode* end = head;
            for(int i = 0; i < n - 1 - loop; ++i)
                end = end->next;
            if(beg->val != end->val) return false;
            ++loop;
            beg = beg->next;
        }
        return true;
    }
};

 

解法3:题目的Follow要求O(n)的时间和O(1)的空间,因此不能循环多次,且不能使用额外的数据结构。考虑到链表只能从头节点开始往后顺序遍历,而验证是否是回文需要从两头往中间逐一判断。题目提示使用两个指针,那么得到两个什么样的指针,在它们顺序往后移动到尾部就能判断出是否是回文呢?例如1-->2-->3-->4-->3-->2-->1,可以看出,如果是回文链表,那么将链表后半段反转后和前半段是一样的!而反转链表可以在O(n)时间,O(1)空间内完成,因此整个时间复杂度也就在O(n),空间复杂度就在O(1)了。具体方法:先用快慢两个指针找到链表中间节点(或者先统计链表长度然后确定中间位置),然后将后半部分链表反转,最后从头开始逐一比较两个半段链表即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        int n = 0;
        ListNode* curr = head;
        while(curr != NULL) {
            ++n;
            curr = curr->next;
        }
        ListNode* beg = head;
        ListNode* end = head;
        for(int i = 0; i < n / 2 + n % 2; ++i)
            end = end->next;
        end = reverseList(end);
        for(int i = 0; i < n / 2; ++i) {
            if(beg->val != end->val) return false;
            beg = beg->next;
            end = end->next;
        }
        return true;
    }
private:
    ListNode* reverseList(ListNode* head) {
        ListNode* rHead = NULL;
        ListNode* pTail = NULL;
        while(head != NULL) {
            ListNode* pNext = head->next;
            if(pNext == NULL) rHead = head;
            head->next = pTail;
            pTail = head;
            head = pNext;
        }
        return rHead;
    }
};

 或者使用快慢指针寻找中间节点:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head == NULL || head->next == NULL) return true;
        ListNode* slow = head, *fast = head;
        while(fast->next != NULL && fast->next->next != NULL) { // 注意判断条件
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode* beg = head, *end = reverseList(slow->next); // 注意后半段的头节点为slow->next
        while(beg != NULL && end != NULL) {
            if(beg->val != end->val) return false;
            beg = beg->next;
            end = end->next;
        }
        return true;
    }
private:
    ListNode* reverseList(ListNode* head) {
        ListNode* rHead = NULL;
        ListNode* pTail = NULL;
        while(head != NULL) {
            ListNode* pNext = head->next;
            if(pNext == NULL) rHead = head;
            head->next = pTail;
            pTail = head;
            head = pNext;
        }
        return rHead;
    }
};

 

posted @ 2015-11-15 16:25  AprilCheny  阅读(202)  评论(0编辑  收藏  举报