Leetcode 234. 回文链表
大约 3 分钟
题目描述:给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 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> vec;
for(ListNode* p = head; p != nullptr; p = p->next) {//O(n)
vec.push_back(p->val); //空间复杂度O(n)
}
for(int i = 0, j = vec.size() - 1; i < j; ++i, --j) { //O(n/2)
if(vec[i] != vec[j]) {
return false;
}
}
return true;
}
};
方法二:反转后半部链表(空间复杂度O(1))
避免使用 O(n) 额外空间的方法就是改变输入。
我们可以将链表的后半部分反转(修改链表结构),然后将前半部分和后半部分进行比较。比较完成后我们应该将链表恢复原样。虽然不需要恢复也能通过测试用例,但是使用该函数的人通常不希望链表结构被更改。
步骤:
- 找到前半部分链表的尾节点。(快慢指针)
- 反转后半部分链表。
- 判断是否回文。
- 恢复链表。
- 返回结果。
Leetcode876.链表的中间结点 (该链表有两个中间结点,返回第二个结点。)
/**
* 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 == nullptr) {
return true;
}
//1.找到前半部分链表的尾节点(找中间结点)
ListNode* fistHalfEnd = endOfFirstHalf(head);
cout << fistHalfEnd->val << endl;
//2.反转后半部分链表。
ListNode* secondHalfStart = reverseList(fistHalfEnd->next);
//3.判断是否回文
ListNode* p1 = head;
ListNode* p2 = secondHalfStart;
while (p2) { //链表长度若为偶数,则p1链长度 == p2链;若为奇数,则p1链长度 = p2链 + 1
if(p1->val != p2->val) {
return false;
}
p1 = p1->next;
p2 = p2->next;
}
//4.还原链表并返回结果
fistHalfEnd->next = reverseList(secondHalfStart);
return true;
}
ListNode* reverseList(ListNode* head) {
ListNode* temp = nullptr;
ListNode* pre = nullptr;
ListNode* cur = head;
while(cur) {
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast->next && fast->next->next) {//该链表有两个中间结点,返回第一个结点。
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};