经典问题
对于链表的结构还不太清晰的同学,可以看我的另一篇文章,实践总结:一篇搞懂链表——单链表和双指针技巧
反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
方法一,迭代法:
在遍历过程中,我们需要维护三个指针:prev(前一个节点),curr(当前节点),和 next_node(下一个节点)。下面是反转链表的步骤和代码实现:
1. 初始化三个指针:
- prev 指针初始化为 None,因为在反转后的链表中,最后一个节点(原链表的头节点)将不会有任何节点指向它。
- curr 指针初始化为 head,即链表的头节点,这是我们开始遍历的地方。
- next_node 用于临时存储 curr.next,在改变 curr.next 之前。
2. 遍历链表,直到 curr 为 None(链表结束):
- 在每次迭代中,首先保存 curr.next 到 next_node。
- 然后,将 curr.next 指向 prev,这样当前节点就反转了它的指向。
- 接下来,移动 prev 和 curr 指针到下一个节点。prev 变为 curr,curr 变为 next_node。
3. 当 curr 为 None 时,遍历结束,此时 prev 指向新的头节点。
# 迭代法
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 定义
prev=None
curr=head
while curr:
new_node=curr.next
curr.next=prev
prev=curr
curr=new_node
return prev
迭代过程的图示展示可以参考这篇文章:看一遍就理解,图解单链表反转
方法二,递归法:
要使用递归的方式反转单链表,我们需要遵循以下步骤:
- 确定基本情况:如果链表为空(head 为 None)或者只有一个节点(head.next 为 None),则链表已经反转,直接返回 head。
- 递归地反转剩余的链表:对 head.next 进行递归调用,反转剩余的链表。
- 在递归调用之后,我们需要将当前节点(head)连接到新反转的链表的末尾。这可以通过将当前节点的 next 指针指向自己(head.next = head),然后将 head 的 next 指针设置为 None 来实现。
- 返回新链表的头节点,它将是原始链表的尾节点。
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseListRecursive(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 基本情况:空链表或只有一个节点
if head is None or head.next is None:
return head
# 递归地反转剩余的链表
new_head = self.reverseListRecursive(head.next)
# 将当前节点连接到新链表的末尾
head.next.next = head
head.next = None
# 返回新链表的头节点
return new_head
不明白的建议看下这个视频,只有三分多钟,讲的很清楚。链表反转(递归法)