题目

https://leetcode-cn.com/problems/reverse-linked-list-ii/

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

说明: 1 ≤ m ≤ n ≤ 链表长度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4

输出: 1->4->3->2->5->NULL

程序

image.png
因为有可能反转第一个节点,所以创建一个哨兵节点 0
在反转的过程中,我们需要保存几个重要的指针,分别是:

  • 第一个反转点的上一个指针(记作:interrupts_node),如上面的1,这个指针最终要指向反转后的第一个指针,如上面的4
  • 第一个反转点的指针(记作: first_reverse_node),如上面的2,这个指针最终要指向最后一个反转指针的下一个指针,如上面的5
  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. # 因为有可能反转第一个节点,所以创建一个哨兵节点
  7. class Solution:
  8. def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
  9. if not head:
  10. return None
  11. dummy = ListNode(0)
  12. dummy.next = head
  13. flag_p = dummy # 标志指针,帮助我们来找到要开始反转的那个节点的上一个节点
  14. pos = 0 # 位置,记录当前走到哪个位置
  15. while flag_p:
  16. # 判断当前的位置是不是位置 m 的上一个位置
  17. # 是的话
  18. if pos == m - 1:
  19. interrupts_node = flag_p # 最终 interrupts_node 节点的 next 节点是反转区间的最后一个
  20. reverse_node = flag_p.next # 要反转的开始节点
  21. sub_cur = None # 子
  22. first_reverse_node = flag_p.next # 第一个反转点的指针 first_reverse_node,这个指针最终要指向最后一个反转指针的下一个指针
  23. while pos < n: # 如果当前位置在 小于位置 n,那么说明需要反转该节点
  24. # 下面就是常规的链表反转
  25. node = reverse_node.next #
  26. reverse_node.next = sub_cur
  27. sub_cur = reverse_node
  28. reverse_node = node
  29. pos += 1
  30. # 两个关键的指针需要指向正确的位置
  31. interrupts_node.next = sub_cur
  32. first_reverse_node.next = node
  33. break
  34. # 不是的话往下走
  35. flag_p = flag_p.next
  36. pos += 1
  37. return dummy.next