题目
给你单链表的头节点head ,请你反转链表,并返回反转后的链表。如下图所示:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
解决思路
- 思路1:3指针交替前进法进行反转
- 初始化3个指针:定义指针pre指向null,定义指针cur指向头节点,定义指针next指向cur的下一个节点。
- 3个指针的作用:
- pre指向已经反转部分链表的头结点。
- cur指向未反转部分链表的头节点。
- next指向cur的下一个节点。
- 思路2:递归反转法
- 先递归遍历到链表的最后一个节点。
- 然后从后向前改变指针的指向。
代码
- 思路1对应的C++代码:
# include <stdio.h>
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 (nullptr == head || nullptr == head->next) {
return head;
}
ListNode *pre = nullptr;
ListNode *cur = head;
ListNode *nex = head->next;
while (cur) {
cur->next = pre;
pre = cur;
(cur = nex) && (nex = nex->next); // 技巧,用&&的作用:当nex为null时不再执行nex = nex->next
}
return pre;
}
};
int main() {
// 创建单链表
ListNode *a = new ListNode(1);
ListNode *b = new ListNode(2);
ListNode *c = new ListNode(3);
ListNode *d = new ListNode(4);
ListNode *e = new ListNode(5);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
ListNode *head = a;
printf("before reverse: ");
while (head)
{
printf("%d ", head->val);
head = head->next;
}
printf("\n");
// 反转单链表
head = a;
Solution *solution = new Solution();
ListNode *ret = solution->reverseList(head);
printf("after reverse: ");
while (ret)
{
printf("%d ", ret->val);
ret = ret->next;
}
return 0;
}
- 思路2对应的C++代码:
# include <stdio.h>
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 (nullptr == head || nullptr == head->next) {
return head;
}
ListNode *cur = head->next; // 指向head的下一个节点
ListNode *pre = reverseList(cur); // 先递归到链表的最后一个节点
head->next = cur->next;
cur->next = head; // 改变指针的指向
cur = cur->next;
return pre;
}
};
int main() {
// 创建单链表
ListNode *a = new ListNode(1);
ListNode *b = new ListNode(2);
ListNode *c = new ListNode(3);
ListNode *d = new ListNode(4);
ListNode *e = new ListNode(5);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
ListNode *head = a;
printf("before reverse: ");
while (head)
{
printf("%d ", head->val);
head = head->next;
}
printf("\n");
// 反转单链表
head = a;
Solution *solution = new Solution();
ListNode *ret = solution->reverseList(head);
printf("after reverse: ");
while (ret)
{
printf("%d ", ret->val);
ret = ret->next;
}
return 0;
}
- 思路1对应的python代码
# -*- coding: utf-8 -*-
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
pre = None
cur = head
nex = head.next
while cur:
cur.next = pre
pre = cur
cur = nex
if nex:
nex = nex.next
return pre
def main():
a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
d = ListNode(4)
e = ListNode(5)
a.next = b
b.next = c
c.next = d
d.next = e
head = a
print('before reverse: ', end='')
while head:
print(head.val, end=' ')
head = head.next
print()
head = a
solution = Solution()
ret = solution.reverseList(head)
print("after reverse: ", end='')
while ret:
print(ret.val, end=' ')
ret = ret.next
if __name__ == "__main__":
main()
- 思路2对应的python代码
# -*- coding: utf-8 -*-
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
# 基于递归进行反转,先遍历到原链表的最后一个节点,然后改变指针的方向
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
cur = head.next
pre = self.reverseList(cur)
head.next = cur.next
cur.next = head
cur = cur.next
return pre
def main():
a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
d = ListNode(4)
e = ListNode(5)
a.next = b
b.next = c
c.next = d
d.next = e
head = a
print('before reverse: ', end='')
while head:
print(head.val, end=' ')
head = head.next
print()
head = a
solution = Solution()
ret = solution.reverseList(head)
print("after reverse: ", end='')
while ret:
print(ret.val, end=' ')
ret = ret.next
if __name__ == "__main__":
main()
说明
- 对应LeetCode第206题。
- 链接:https://leetcode-cn.com/problems/reverse-linked-list/