以下代码表示切片功能的实现 假设 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)中执行相同的功能吗?
答案 0 :(得分:2)
假设这两个参数已经在链接中,我认为这可以工作。
绘制图片会更容易理解
[l1.prev]-[l1]-[l1.next]---[l2.prev]-[l2]-[l2.next]
这个想法是你要
l1.prev.next = l2.next
以加入从左向右移动的列表l2.next.prev = l1.prev
以加入从右向左移动的列表l1.prev = None
和l2.next = None
以从初始列表中删除l1
到l2
l1
,拼接的子列表。 我可能已经把这些步骤搞砸了,但也许是这样的
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。总是O(n)。没有办法像使用数组那样“跳转”到链接列表中。
好消息是2.是O(1)操作。
这是什么意思?
好吧,如果你拿一个列表并希望在 n 元素之后对其进行切片,那么你需要遍历那么多元素然后将其切片。
但是,如果您已经在列表上执行操作,则可能引用了要进行剪切的列表元素。在这种情况下,您无需再次浏览列表。
我在上周写的一些代码中使用了这个效果。