Leetcode P0234"Palindrome Linked List" 题解

2020/11/12 Leetcode

博文中会简要介绍Leetcode P0234题目分析及解题思路。

“Palindrome Linked List”是中规中矩的题目。题目的难点并不在于判断链表是否是回文链,而是在于控制时间复杂度在O(n)且空间复杂度为O(1)。本篇博文不会详细讲解空间复杂度为O(1)的方法,但是需要强调的是这种方法其实是本文解法的一种衍生。

Given a singly linked list, determine if it is a palindrome.

这道题的基本思路很简单,为了对称地比较一个链表前后端结点的值,我们可以将原链表翻转得到新链表,然后将新链表和原链表中的所有对应的结点逐一按序比较即可。

这个思路的衍生则是可以只翻转原链表的一半,例如后一半的链表,然后将原来的前一半链表和翻转后的后一半链表按序依次比较即可,这样可以控制时间复杂度为O(1)。不过无论是原型还是衍生,两个解法的时间复杂度都是O(n)。

以下是Java的题解代码实现。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode reversed = this.reverse(head);
        ListNode p1 = head, p2 = reversed;
        while (p1 != null) {
            if (p1.val != p2.val)
                return false;
            
            p1 = p1.next;
            p2 = p2.next;
        }
        
        return true;
    }
    
    private ListNode reverse(ListNode head) {
        ListNode headNew = null, curr = head;
        while (curr != null) {
            ListNode node = new ListNode(curr.val, headNew);
            headNew = node;
            curr = curr.next;
        }
        
        return headNew;
    }
}

以下是C++的题解代码实现。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode *reversed = this->_Reverse(head);
        ListNode *p1 = head, *p2 = reversed;
        while (p1) {
            if (p1->val != p2->val)
                return false;
            
            p1 = p1->next;
            p2 = p2->next;
        }
        
        return true;
    }
    
private:
    ListNode* _Reverse(ListNode *head) {
        ListNode *head_new = nullptr, *curr = head;
        while (curr) {
            ListNode *node = new ListNode(curr->val, head_new);
            head_new = node;
            curr = curr->next;
        }
        
        return head_new;
    }
};

Search

    Table of Contents