给定一个链表的 头节点 head ,请判断其是否为回文链表。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题
可以使用快慢指针和链表反转的方法来判断链表是否为回文链表。具体步骤如下:
- 使用快慢指针找到链表的中间节点。
- 反转链表的后半部分。
- 将前半部分链表与翻转后的后半部分链表进行比较。
- 恢复链表原来的结构(可选)。
bool isPalindrome(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return true;
}
ListNode* slow = head;
ListNode* fast = head;
// 使用快慢指针找到链表的中间节点
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* secondHalf = reverseList(slow->next); // 反转链表的后半部分
ListNode* firstHalf = head;
// 比较前半部分链表和翻转后的后半部分链表
while (secondHalf != nullptr) {
if (firstHalf->val != secondHalf->val) {
return false;
}
firstHalf = firstHalf->next;
secondHalf = secondHalf->next;
}
return true;
}
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
上述代码中用到了一个辅助函数 reverseList 用于反转链表的后半部分。该函数的时间复杂度为 O(n),空间复杂度为 O(1)。整体的时间复杂度为 O(n),空间复杂度为 O(1)。