234.Palindrome Linked List
Given the head
of a singly linked list, return true
if it is a palindrome or false
otherwise.
Example 1:
1 2
| Input: head = [1,2,2,1] Output: true
|
Example 2:
1 2
| Input: head = [1,2] Output: false
|
递归法:
时间复杂度:O(n)
空间复杂度:O(n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public: ListNode* frontPointer; bool recursivelyCheck(ListNode* currentNode) { if (currentNode != nullptr) { if (!recursivelyCheck(currentNode->next)) { return false; } if (currentNode->val != frontPointer->val) { return false; } frontPointer = frontPointer->next; } return true; }
bool isPalindrome(ListNode* head) { frontPointer = head; return recursivelyCheck(head); } };
|
这种方法不仅使用了 O(n)的空间,且比将链表复制到数组方法更差,因为在许多语言中,堆栈帧的开销很大(如 Python),并且最大的运行时堆栈深度为 1000(可以增加,但是有可能导致底层解释程序内存出错)。为每个节点创建堆栈帧极大的限制了算法能够处理的最大链表大小。
快慢指针:
时间复杂度:O(n)
空间复杂度:O(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| class Solution { public: bool isPalindrome(ListNode* head) { if (head == nullptr) { return true; }
ListNode* firstHalfEnd = endOfFirstHalf(head); ListNode* secondHalfStart = reverseList(firstHalfEnd->next);
ListNode* p1 = head; ListNode* p2 = secondHalfStart; bool result = true; while (result && p2 != nullptr) { if (p1->val != p2->val) { result = false; } p1 = p1->next; p2 = p2->next; }
firstHalfEnd->next = reverseList(secondHalfStart); return result; }
ListNode* reverseList(ListNode* head) { ListNode* prev = nullptr; ListNode* curr = head; while (curr != nullptr) { ListNode* nextTemp = curr->next; curr->next = prev; prev = curr; curr = nextTemp; } return prev; }
ListNode* endOfFirstHalf(ListNode* head) { ListNode* fast = head; ListNode* slow = head; while (fast->next != nullptr && fast->next->next != nullptr) { fast = fast->next->next; slow = slow->next; } return slow; } };
|