- 反转链表
- 解法一:迭代
- 解法二:递归
解法一:迭代题目描述:给你单链表的头节点
head
,请你反转链表,并返回反转后的链表。
示例:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
由题目很容易想到,可以直接修改指针指向。
例如:本来是1->2
,那么只需要将指针指向反转即可,即1<-2
;
若为1->2->3->4->5
,那么直接依次进行反转,最终得:1<-2<-3<-4<-5
这种方法需要额外占有变量进行存储,因为每次修改指针指向后,链表已经断裂,无法或许下个结点的信息。
例如:对1->2->3->4->5
在修改节点1
的指针指向时,此时修改之后为null<-1
和 2->3->4->5
,此时想要继续修改节点2
的指针指向时,已经无法获取指向节点2
的指针了。
另外,在修改节点2
的指针时,需要知道节点2
前一个节点(即节点1
需要将其指向前一个节点,1<-2
)。
所以我们首先需要一个额外变量存储当前节点的next
,另外还需要一个节点存储当前节点的prev
,下面看图解。
修改节点1
的指针指向:
继续修改下一个节点指针,变量pfront
、p
、tmp
均做出相应修改:
代码如下:
/**
* 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* p = head;
ListNode* pfront = nullptr;
while(p != nullptr){
ListNode* tmp = p->next;
p->next = pfront;
pfront = p;
if(tmp == nullptr)
break;
p = tmp;
}
return p;
}
};
解法二:递归
递归的解法比较难想到,官方的题解也给的很明确,这里我看了评论区又自己画图理解了一下,觉得还可以。
大致思路就是:
若初始链表为:
而我们此时
n
k
+
1
n_{k+1}
nk+1之后的均已经反转,且我们所处位置为
n
k
n_k
nk:
那么我们所需要做的就是首先修改
n
k
n_{k}
nk和
n
k
+
1
n_{k+1}
nk+1之间的指针:nk->next->next = nk
然后修改
n
k
n_{k}
nk的指针:nk->next = null
代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next) {
return head;
}
ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
};
假设原始链表为1->2->3->4->5
,自己推了一遍函数调用过程:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)