题目 92. 反转链表 II
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list-ii
解题思路
见代码注释,同时参照以下图片
代码
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def reverseBetween(self, head, m, n):
'''
用递归方式反转链表的前n个节点,注意要记录第n+1个节点(为反转后链表的后继节点),
返回反转后的子链表的头指针
'''
successor = None
def reverse(head, n):
global successor
if n == 1:
successor = head.next # 反转后链表的后继节点
return head
# 把reverse(head.next, n-1)看做是:
# 一个已经实现了 反转以head.next为头结点的前n-1个节点的功能,且返回了新的头结点(last)。(参照上两张图片)
# 不要跳进递归,⽽是利⽤明确的定义来实现算法逻辑。
last = reverse(head.next, n-1)
head.next.next = head
head.next = successor
return last
# 整个都采用递归方式
# if m == 1:
# return self.reverse(head, 1, n)
# else:
# return self.reverseBetween(head.next, m-1, n-1)
# 边缘情况
if m == n:
return head
if m == 1:
return reverse(head, n)
# 迭代,找第m-1个节点
res = head # 最终的头结点
t = m
while t > 2 and head.next != None:
head = head.next
t -= 1
precursor = head # 第m-1个节点即为 反转后的子链表的前驱节点
last = reverse(head.next, n-m+1) # 需要注意是n-m+1,last为需要反转以后的子链表的头结点
precursor.next = last
return res
# s = Solution()
# node1 = ListNode(1)
# node2 = ListNode(2)
# node3 = ListNode(3)
# node4 = ListNode(4)
# node5 = ListNode(5)
# node1.next = node2
# node2.next = node3
# node3.next = node4
# node4.next = node5
# node5.next = None
# print_list(node1)
# # print_list(s.reverseBetween(node1, 1, 4))
# print_list(s.reverseBetween(node1, 2, 4))