一、题目
- 原题链接
- 描述:给你单链表的头指针head和两个整数left和right,其中left<= right。请你反转从位置left到位置right的链表节点,返回反转后的链表。
- 示例1
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5] - 示例2
输入:head = [5], left = 1, right = 1
输出:[5]
二、题解
-
思路:首先这是个要求翻转链表中的一部分的题目,前几天做过一个翻转整个链表的题(之后发个贴),自然想到考虑定义一个全部翻转的函数reverseList(),在此基础上把left到right之间的链表段全部翻转,然后再连接左边和右边的链表段即可完成。
-
步骤:(如下图)
1.断开:head至pre(即left的前一个结点)为一段,left至right为一段,cur(即right.next)至末端为一段
2.翻转:对left至right的一段链表调用reverseList()全部翻转
3.连接:令pre的下一个结点为翻转后的链表的left,令翻转后的链表的right结点的下一个结点为cur
4.return -
注意点
1.(来自官方题解)这点我不太理解
因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
2.要注意切断连接,即
# 注意:切断链接
pre.next = None
right_node.next = None
3.注意要弄清楚要走多少步
4.最后返回dummy_node.next是正确的,但我试过返回head,有些测试用例不能通过(比如left和right恰好分别是链表的首尾时)
三、代码(Python3)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
# 翻转整个链表
def reverseList(head:ListNode):
if head is None or head.next is None:
return head
newHead = reverseList(head.next)
head.next.next = head
head.next = None
# return newHead
# 使用虚拟头节点
dummy_node = ListNode(-1)
# dummy_node的下一个节点就是head
dummy_node.next = head
# 从dummy_node开始向后走
pre = dummy_node
# 走left-1步到达left的前一个结点
for i in range(left-1):
pre = pre.next
# 从pre结点(即left前一个结点)开始向后走
right_node = pre
# 走right-left+1步到达right结点
for i in range(right-left+1):
right_node = right_node.next
# 截取left至right的链表
left_node = pre.next
cur = right_node.next
# 切断链接
pre.next = None
right_node.next = None
# 反转截取的left至right的链表
reverseList(left_node)
# 把反转后的链表接上原来的前后两段
pre.next = right_node
left_node.next = cur
# 返回接好后的链表
return dummy_node.next