给你一个单链表的头节点 head
,请你判断该链表是否为
回文链表
。如果是,返回 true
;否则,返回 false
。
示例 1:
输入:head = [1,2,2,1] 输出:true
示例 2:
输入:head = [1,2] 输出:false
解答:数组保存,判断头尾是否相等
/**
* 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) {
vector<int> list;
while (head) {
list.push_back(head->val);
head = head->next;
}
for (int i = 0, j = list.size() - 1; i < list.size() / 2; i++, j--) {
if (list[i] != list[j]) {
return false;
}
}
return true;
}
};
优化空间复杂度:快慢指针 - 反转后半段链表 - 对比两段链表,付出的额外空间只有反转链表时用的临时指针。
注意:在分割链表后反转时,取后半段反转,比如 1 3 4 3 1,reverse(3 1),而不是reverse(4 3 1),要不然会导致前半段溢出。或者判断时候用前半段也行。
快慢指针:
ListNode* halfList(ListNode* head) {
ListNode *fast = head, *slow = head;
while (fast->next != NULL && fast->next->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
反转链表:
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
ListNode* cur = head;
while (cur!=NULL) {
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
整体代码:
/**
* 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) {
if (head == NULL) {
return true;
}
ListNode* p1 = head;
ListNode* second = halfList(head);
// 注意溢出判断是前半段还是后半段
// ListNode* p2 = reverseList(second->next);
// for (; p2 != NULL;) {
ListNode* p2 = reverseList(second);
for (; p1 != NULL;) {
if (p1->val != p2->val) {
return false;
} else {
p1 = p1->next;
p2 = p2->next;
}
}
return true;
}
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
ListNode* cur = head;
while (cur != NULL) {
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
ListNode* halfList(ListNode* head) {
ListNode *fast = head, *slow = head;
while (fast->next != NULL && fast->next->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};