【问题标题】:how to place a linked list node from a list of linked lists onto a heap in python如何将链表节点从链表列表放置到python中的堆上
【发布时间】:2022-01-05 11:57:19
【问题描述】:

我认为标题比实际问题描述更令人困惑。所以这里是

我有一个python 链表列表,看起来像lists = [[1,4,5],[1,3,4],[2,6]],链表节点定义为

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

在我试图解决的问题中,第一步是将每个列表的第一个元素放入堆中。这是我的代码:

mylist1 = ListNode(1, ListNode(4, ListNode(5)))
mylist2 = ListNode(1, ListNode(3, ListNode(4)))
lists = [mylist1, mylist2]

import heapq
heap = []
for l in lists:
    heapq.heappush(heap, (l.val, l))

当我运行此代码时,出现以下异常:

Traceback (most recent call last):
  File "<pyshell#29>", line 2, in <module>
    heapq.heappush(heap, (l.val, l))
TypeError: '<' not supported between instances of 'ListNode' and 'ListNode'

我想我明白那里发生了什么,pythonl 不作为单个节点,而是作为一个完整的列表。所以我的问题是,如何将每个列表中的第一个节点放入python 的堆中?我觉得答案很简单,但我错过了一些重要的东西。

编辑

我正在尝试解决这个问题,https://leetcode.com/problems/merge-k-sorted-lists/。方法是使用堆,但我不想将所有元素都插入其中,我想做的是插入每个列表的第一个元素,找到最小元素,然后从列表中插入下一个元素有最小值等等,直到我遍历所有元素。

【问题讨论】:

  • heapq 实现了一个最小堆,当你插入时它会在堆中的元素之间进行一些比较。您插入了 (int, ListNode) 的 2 个元组,并且由于元组中第一项的 int 值存在平局,因此它移至比较中的第二项。 ListNodes 没有实现比较,这导致了错误。我认为这与将l 视为列表无关。
  • 请说明您试图解决哪个更高级别的问题?这里的大局是什么?
  • @trincot 我在问题末尾添加了一个编辑。

标签: python linked-list heap


【解决方案1】:

(l.val, l) 放在堆上的问题在于,当两个元组在第一个成员(val)中具有相同的值时,就会在第二个成员值之间进行比较,即在列表之间。但是这个操作没有定义。您可以避免这种情况,方法是在您已经拥有的两个成员之间在这些元组中放置第三个唯一值。所以你可以像这样定义你的堆:

for i, l in enumerate(lists):
    heapq.heappush(heap, (l.val, i, l))

由于列表可以为空,您应该添加一个条件:

for i, l in enumerate(lists):
    if l:
        heapq.heappush(heap, (l.val, i, l))

这也是告诉你,首先将这些元组收集到标准列表中,然后在其上调用heapify 更有效:

heap = [(l.val, i, l) for i, l in enumerate(lists) if l]
heapq.heapify(heap);

不是你的问题,但如果你不能使完整的逻辑工作,这里是代码的 rest 的剧透:

tail = dummy = ListNode() while heap: _, i, tail.next = heap[0] tail = tail.next if tail.next: heapq.heapreplace(heap, (tail.next.val, i, tail.next)) else: heapq.heappop(heap) return dummy.next

【讨论】:

  • for i, l in enumerate(lists) 的代码无效。我收到一条错误消息,TypeError: '&lt;' not supported between instances of 'int' and 'ListNode'。但是 heap.heapify(heap) 的代码有效。你介意解释发生了什么吗?我不太清楚它为什么起作用。我错过了什么?
  • 这意味着并非堆中的所有元组都具有这 3 个元素。确保始终使用 3 元元组,中间元素是唯一的 i 编号。
  • 看到它在repl.it上运行。
  • 您是否将您的代码与我的代码进行了比较?是否清楚遗漏了什么?
【解决方案2】:

你在寻找这样的东西吗? =>

class ListNode:
def __init__(self, val=0, next=None):
    self.val = val
    self.next = next
def __lt__(self,other):
    return self.val < other.val
def __le__(self,other):
    return self.val <= other.val


mylist1 = ListNode(1, ListNode(4, ListNode(5)))
mylist2 = ListNode(1, ListNode(3, ListNode(4)))
nodes = [mylist1,mylist2]

import heapq
heap = []
for l in nodes:
    heapq.heappush(heap, (l.val,l))
print(heap)

也看看这个 => heapq push TypeError: '<' not supported between instances

【讨论】:

  • 不,这不是我要找的。我想要的只是将每个列表的第一个元素放入堆而不是其他元素。
  • 这个怎么样?我已经编辑了我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 2015-03-08
  • 2018-06-03
  • 2020-03-17
  • 2012-04-26
  • 2011-09-19
  • 2020-10-30
相关资源
最近更新 更多