leetcode 每日一题 92. 反转链表 II
双指针遍历反转
思路:
①创建cur,pre指针分别指向当前节点和当前节点的前一节点。
②遍历链表直到cur指向要翻转链表的起始位置,此时cur所指向的节点将会是翻转后链表的最后一个节点,pre所指向的节点的下一个节点应该是翻转后链表的第一个节点,我们用tail和con记录下当前cur和pre的节点位置,为接下来链表的翻转作准备。
③此时要做的操作是从cur节点开始,将此节点和接下来的m-n个节点进行翻转。先用一个temp记录cur指向的下一个节点,将cur指向下一个节点变为pre,再将pre指向cur节点,cur指向temp。直到操作完后面的m-n个节点。
④此时cur指向的是原始链表中要翻转链表尾部的下一个节点,pre指向原始链表中要翻转链表尾部。则让tail.next = cur,con.next = pre即可,(这里要注意的是,如果m=1,意味着从头开始翻转,则con为空,直接将pre作为头节点返回即可)
代码:
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: if not head: return None cur, prev = head, None while m > 1: prev = cur cur = cur.next m, n = m - 1, n - 1 tail, con = cur, prev while n: temp = cur.next cur.next = prev prev = cur cur = temp n -= 1 if con: con.next = prev else: head = prev tail.next = cur return head
头插法
思路:
先遍历找到要翻转链表前一个节点prev,tail记录要翻转链表的首个节点,利用头插法将该节点后面m-n+1个节点插入,tail的下一个节点指向要翻转链表尾部的下一个节点即可。
代码:
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: if not head: return None dummy = ListNode(-1) dummy.next = head cur, prev = head, dummy while m > 1: prev = cur cur = cur.next m, n = m - 1, n - 1 tail = cur while n: temp = cur cur = cur.next temp.next = prev.next prev.next = temp n -= 1 tail.next = cur return dummy.next