手写链表反转
题目:Leetcode-206. 反转链表
给你单链表的头节点
head
,请你反转链表,并返回反转后的链表输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
对于链表反转的问题,想起来其实非常简单。
就是从前往后,将节点一个一个采用头插法的做成一个新链表嘛,这样新链表就是旧链表的反转链表啦!
那既然这么简单,为什么还要学习链表反转呢?
因为,这个思想非常地常用,比如指定区间反转,链表k个一组反转等等
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* headNode = new ListNode();
ListNode* curNode = head; // 当前插入节点
while(curNode != nullptr) {
auto nextNode = curNode->next; // 记录下一个节点
// 将当前节点插入到新节点头部
curNode->next = headNode->next;
headNode->next = curNode;
curNode = nextNode;
}
return headNode->next;
}
};
纯头指针
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* curNode = head;
head = nullptr;
while(curNode != nullptr) {
auto nextNode = curNode->next;
curNode->next = head;
head = curNode;
curNode = nextNode;
}
return head;
}
};
递归实现
第三种不太好理解的方法,我们采用递归的方法来实现。2
怎么样递归呢?化整为零,先递到最后的一个节点,然后依次返回后面节点反转后的结果。文章来源:https://www.toymoban.com/news/detail-632322.html
借助示意图进行理解:
文章来源地址https://www.toymoban.com/news/detail-632322.html
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 退出递归的条件
if(head == nullptr || head->next == nullptr) {
return head;
}
ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
};
到了这里,关于算法村第二关(1)——手写链表反转的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!