O(1)中的双链表切片?

时间:2017-06-18 15:52:27

标签: python linked-list time-complexity

以下代码表示切片功能的实现 假设 l1 l2 是Node类的对象(属性 id,next,prev )。

我想返回 l1 l2 l1 l2 )之间的元素,以及然后显然改变了prev和下一个值,因为这个切片不再存在了:

def splice(self, l1, l2):
        curr = l1
        s = ""
        while curr.next:
            s += str(curr) + "\n"
            if curr is l2:
                break
            curr = curr.next
        if l1.prev is not None:
           l2.prev = l1.prev
        else:
           self.first = l2.next
           self.first.prev = None

        if l2.next is not None:
           l1.next = l2.next
        else:
            self.last = l2.next
        return s

我把这个代码加倍,时间复杂度是O(1),我认为它会是O(n) 因为While循环。
无论如何我在O(1)中执行相同的功能吗?

2 个答案:

答案 0 :(得分:2)

假设这两个参数已经在链接中,我认为这可以工作。

绘制图片会更容易理解

[l1.prev]-[l1]-[l1.next]---[l2.prev]-[l2]-[l2.next]

这个想法是你要

  1. 设置l1.prev.next = l2.next以加入从左向右移动的列表
  2. 设置l2.next.prev = l1.prev以加入从右向左移动的列表
  3. 设置l1.prev = Nonel2.next = None以从初始列表中删除l1l2
  4. 返回l1,拼接的子列表。
  5. 我可能已经把这些步骤搞砸了,但也许是这样的

    def splice(self, l1, l2):
       before, next = l1.prev, l2.next
    
       # self.head = ... # TODO: Figure out what this should point at          
    
       if l2.next:
           l2.next.prev = before if l1 else None  # right-to-left
       if l1.prev:
           l1.prev.next = next if l2 else None # left-to-right
    
       if l1:
           l1.prev = None # detach <-l1
       if l2:
           l2.next = None # detach l2->
    
       return l1  # return the sublist 
    

    请注意,同时找到l1和l2都是O(N)操作

答案 1 :(得分:1)

分割链表有两个部分:

  1. 寻求要分割的节点
  2. 拆分列表
  3. 不幸的是,1。总是O(n)。没有办法像使用数组那样“跳转”到链接列表中。

    好消息是2.是O(1)操作。

    这是什么意思?

    好吧,如果你拿一个列表并希望在 n 元素之后对其进行切片,那么你需要遍历那么多元素然后将其切片。

    但是,如果您已经在列表上执行操作,则可能引用了要进行剪切的列表元素。在这种情况下,您无需再次浏览列表。

    我在上周写的一些代码中使用了这个效果。