Reverse a single linked list with 0(n) time complexity

LeetCode 92

Reverse a linked list from position m to n. Do it in one-pass. 注意必须使用O(n)的复杂度来实现

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

思路:一开始的思路是使用start指针,找到第一个要换的位置p1,然后再通过遍历去找到交换的位置p2,接着进行互换。但这种算法的复杂度是o(n+k*2)。

我们希望能够有两个指针:ptr1,ptr2,ptr1指向交换的开始,ptr2指向交换的结束。每次交换将ptr1前进一位,将ptr2回退一位直到相交。

问题:但是因为这是一个单链表,无法直接从一个位置取得它的前一个node,所以我们需要用一个方法来得到前一个node

解决方法:使用递归的方法来取得上一位,根据递归的特性,每次返回都会从stack中取出上一次调用的局部变量,我们刚好可以通过这个特性来取得一个NODE的前一个NODE。(因为我们通过node.next来调用递归)

大体思路:

1.先通过递归来将left和right指针移动到交换起始和结束位置。

2.将left和right的值交换后返回上一次调用. 这样返回后right就指向前一次的node了。

但是left会在返回的时候向前移动,如何让他向后移动呢?

我们将left保存为全局变量,手动在每次交换后让left = left.next.

class Solution:
    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
        left, right = head, head
        stop = False # 判断停止交换的flag
        ptr = head
        if head == None:
            return head
        def oneStep(right, m, n):
            # exit
            nonlocal left, stop #定义使用全局变量left和stop
            if m > 1:
                left = left.next #移动到交换的开始位置
            if n == 0:
                return #移动到交换的结束位置的后一位,返回
            else:
                oneStep(right.next, m-1, n-1) #如果还没到结尾,递归向后
            if left== right or right.next == left: #停止交换
                stop = True
            if stop == False: 
                left.val, right.val = right.val, left.val
                left = left.next
        oneStep(ptr, m, n)
        return head

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值