206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
题意
给一个链表,将链表进行翻转
思路
- 用两个指针维护相邻两个点,每次把后面一个点指向前一个点,直到后一个点指向空,最后把第一个节点指向空。
- 也可以递归处理,把head->next翻转,然后把head->next节点指向head,head->next置为空。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head) return NULL;
auto a = head, b = head->next;
while(b){
auto c = b->next;
b->next = a;
a = b;
b = c;
}
head->next = NULL;
return a;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head || !head->next) return head;
auto tail = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return tail;
}
};
234. 回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
题意
判断一个链表是否为回文链表
思路
先将链表后一半进行翻转,然后用两个指针从头尾遍历,判断对应节点的值是否相等,不等则不是回文链表,最后把链表还原。
代码
class Solution {
public:
bool isPalindrome(ListNode* head) {
int n = 0;
for(auto i = head;i; i = i->next) n++;
if(n<=1) return true;
int half = n / 2;
auto a = head;
for(int i = 0; i < n - half; i++) a = a->next;
auto b = a->next;
for(int i = 0; i < half - 1;i++){
auto c = b->next;
b->next = a;
a = b;
b = c;
}
auto p = head, q = a;
bool success = true;
for(int i = 0; i < half; i++){
if(p->val != q->val){
success = false;
break;
}
p = p->next;
q = q->next;
}
auto tail = a;
b = a->next;
for(int i = 0; i < half - 1; i++){
auto c = b->next;
b->next = a;
a =b, b = c;
}
tail->next = NULL;
return success;
}
};