【leetcode系列】【算法】【中等】反转链表 II

题目:

题目链接: https://leetcode-cn.com/problems/reverse-linked-list-ii/

解题思路:

方法一:数组 + 新链表

因为题目中并没有要求必须使用原节点,所以只需要将对应的节点值进行交换就行

所以比较简单的方法,就是将所有节点中的值,放到一个数组中,将对应值进行交换,然后生成新链表

数组值交换的方法为:

  1. 交换m和n下标对应的值
  2. m向右移,n向左移,继续交换值,直到m >= n为止

图示如下:

方法二:递归

如果利用递归,其实可以对单向链表实现类似方法一中的功能,图示流程如下:

变量:

  1. left : 左边需要交换值的节点,全局变量
  2. right : 右边需要交换值的节点,递归变量
  3. stop: 是否停止递归,全局变量

逻辑图示如下:

开始时,每次递归,如果left如果没移动到开始节点,每次将left向右移动1;right如果没移动到结束节点,向右移动一

此时停止移动left和right,交换left和right的值,并将全局变量left向右移动1,返回上一层递归

因为right是递归变量,并且刚刚只是交换了值,并没有修改节点的顺序

所以在返回上一层递归时,实现了类似双向链表prev的功能,使得right回退到了前一个节点,如下图所示:

此时再次交换值,并向右移动left,返回上一层递归:

此时发现left和right指向同一个节点,修改全局变量stop为True,停止上层递归的所有交换值操作,完成值的交换

代码实现:

方法一:

# 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:
        val_lst = []
        while head:
            val_lst.append(head.val)
            head = head.next
            
        m -= 1
        n -= 1
        while m < n:
            val_lst[m], val_lst[n] = val_lst[n], val_lst[m]
            m += 1
            n -= 1
            
        dummy = ListNode(0)
        new_head = dummy
        for val in val_lst:
            new_head.next = ListNode(val)
            new_head = new_head.next
            
        return dummy.next

方法二:

# 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 or m >= n:
            return head
        
        left, right = head, head
        stop = False
        
        def reverse_help(right, m, n):
            nonlocal left, stop
            
            if n <= 1:
                return
            
            right = right.next
            
            if m > 1:
                left = left.next
                
            reverse_help(right, m - 1, n - 1)
            
            if not stop:
                left.val, right.val = right.val, left.val
                left = left.next

            if left is right or left.next is right:
                stop = True

        reverse_help(right, m, n)
        return head
发布了100 篇原创文章 · 获赞 4 · 访问量 1469

猜你喜欢

转载自blog.csdn.net/songyuwen0808/article/details/105319300