题目来源:https://leetcode.cn/problems/reverse-linked-list/description/
C++题解1:声明一个vector<int> 数据类型,将原链表中的数据存放进容器,再用一个新链表,从容器末端一一读取元素,从而实现链表反转。
/**
* 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:
ListNode* reverseList(ListNode* head) {
ListNode* ptr = head, *revptr = nullptr;
vector<int> a(0);
if(head == nullptr) return nullptr;
while(ptr){
a.push_back(ptr->val);
ptr = ptr->next;
}
int len = a.size();
revptr = new ListNode(a[len-1]);
ListNode* curptr = revptr;
for(int ii = len-2; ii >= 0; ii--){
ptr = new ListNode(a[ii]);
curptr->next = ptr;
curptr = curptr->next;
}
return revptr;
}
};
C++题解2:声明三个指针,一个指向上一个节点preptr,一个指向当前节点curptr,一个指向下一个节点。从原链表往下走,curptr的指针反向指向preptr,preptr指针更新到curptr;如果nexptr的next不为空,那么curptr走到nexptr,nexptr走向nexptr->next;但如果nexptr的next为空,那么nexptr得指向curptr,然后curptr走到nexptr,才能使原链表的末尾节点指向倒数第二个节点。
/**
* 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:
ListNode* reverseList(ListNode* head) {
if(!head) return nullptr;
ListNode* preptr = nullptr, *curptr = head, *nexptr = head->next;
while(nexptr){
curptr->next = preptr;
preptr = curptr;
if(nexptr->next){
curptr = nexptr;
nexptr = nexptr->next;
}
else {
nexptr->next = curptr;
curptr = nexptr;
break;
}
}
return curptr;
}
};
两种解法都要单独考虑原链表为空的情况。
网上解法1:大致思路与题解2相同,简洁一点点,因为题解2指针多走了一步
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp; // 保存cur的下一个节点
ListNode* cur = head;
ListNode* pre = NULL;
while(cur) {
temp = cur->next; // 保存一下 cur的下一个节点,因为接下来要改变cur->next
cur->next = pre; // 翻转操作
// 更新pre 和 cur指针
pre = cur;
cur = temp;
}
return pre;
}
};
网上解法2:递归法。last可以不断递归直到指向末节点再往回走。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 边缘条件判断
if(head == NULL) return NULL;
if (head->next == NULL) return head;
// 递归调用,翻转第二个节点开始往后的链表
ListNode *last = reverseList(head->next);
// 翻转头节点与第二个节点的指向
head->next->next = head;
// 此时的 head 节点为尾节点,next 需要指向 NULL
head->next = NULL;
return last;
}
};