反转链表之递归操作链表

题目 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))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章