leetcode234. 回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为
回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
题目描述
给定一个单链表,编写一个函数判断该链表是否为回文链表。
算法分析
这个问题可以通过快慢指针法来解决。我们首先找到链表的中间节点,然后将链表的后半部分反转。最后,我们比较链表的前半部分和反转后的后半部分是否相同。
算法步骤
- 初始化两个指针
slow
和fast
都指向链表的头节点。 - 使用快慢指针法找到链表的中间节点,即
slow
指针指向的位置。 - 反转链表的后半部分,使用
reverseList
函数。 - 比较链表的前半部分和反转后的后半部分是否相同。
- 返回结果。
算法流程
具体代码
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* reverseList(ListNode* head) {
ListNode* pre = nullptr;
ListNode* cur = head;
while (cur) {
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
bool isPalindrome(ListNode* head) {
ListNode* mid = middleNode(head);
ListNode* head2 = reverseList(mid);
while (head != mid) {
if (head->val != head2->val)
return false;
head = head->next;
head2 = head2->next;
}
return true;
}
};
算法分析
复杂度分析
- 时间复杂度:O(n),其中 n 是链表的长度。我们需要遍历链表一次。
- 空间复杂度:O(1),我们不需要额外的空间,除了几个指针。
易错点
- 在使用快慢指针法时,确保正确地找到链表的中间节点。
- 在反转链表时,确保正确地反转链表的节点。
- 在比较链表的前半部分和后半部分时,确保正确地比较它们的值。
注意事项
- 确保在遍历链表时不要超出链表的边界。
- 在处理链表节点时,确保不会覆盖任何节点。