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?

Link:

https://leetcode.com/problems/palindrome-linked-list/#/description

解题方法:

难点在于如果在O(n) time and O(1) space解决这个问题。
可以用找链表中位数+反转后一半链表的方法处理链表,然后对比左半段链表和右半段链表。
找中位数用快慢指针非常简单,因为实际上是找到右半段链表前面一个结点,所以都不需要考虑奇偶问题,当快指针触底直接返回慢指针就可以。

不用额外空间反转链表(递归):
输入参数:右边结点的第一个作为curr,和这个结点的前一个结点作为prev
函数出口:当curr->next == NULL时,直接修改currnext为记录的前一个节点,返回这个节点也就是反转后的head
函数体:用一个next记录curr->next,然后使curr->next = prev;完成一次反转,将next作为下一次的curr,现在的curr作为下一次的prev

Tips:

在反转链表时,不要把prev初始化为中位数的那个结点,这样最后比较的时候会进入死循环,应该把prev初始化为NULL

Time Complexity:

时间:O(N)
空间:O(1)

完整代码:

bool isPalindrome(ListNode* head) 
    {
        if(head == NULL || head->next == NULL)
            return true;
        ListNode* median = findMedian(head);
        ListNode* rList = reverseList(NULL, median->next);
        ListNode* lList = head;
        while(rList != NULL)
        {
            if(rList->val != lList->val)
                return false;
            rList = rList->next;
            lList = lList->next;
        }
        return true;
    }
    ListNode* reverseList(ListNode* prev, ListNode* curr)
    {
        if(curr->next == NULL)
        {
            curr->next = prev;
            return curr;
        }
        ListNode* N = curr->next;
        curr->next = prev;
        return reverseList(curr, N);
    }
    ListNode* findMedian(ListNode* head)
    {
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast != NULL)
        {
            if(fast->next == NULL || fast->next->next == NULL)
                return slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }

你可能感兴趣的:(Palindrome Linked List解题报告)