0

Solving leetcode # 23 "Merge K Sorted Linked lists" (you can read more about it here) I've stumbled upon some baffling behaviour from heapq: I needed a more customized comparator for the list nodes to ensure ones with higher following values in the linked lists would be prioritized when keys in the heap were the same. So I created a quick wrapper class for the ListNode class offered. My python is pretty weak - but I can't for the life of me understand a) why I'm getting an index out of bounds error indicating that heap is empty when it shouldn't be and b) how it's possible the length of the heap print statement is printing twice without being called twice. The test case being used is represented via their node values in a list as "[[1,4,5],[1,3,4],[2,6]]."

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

import heapq as hq

class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        heap = []
        hq.heapify(heap)
 
        #create initial heap
        #insert beginning of each list into priority queue
        for a_list in lists:
            if a_list:
                hq.heappush(heap, HeapNode(a_list))   
    
        #DEBUG
        #print(heap)
        #for h in heap: print(h.priority)
        print("len of heap: ", len(heap))
        print("heap[0]: ", heap[0])

        #scroll through and unwrap class to create single sorted LL
        head = hq.heappop(heap).list_node 
        tail = head
        while len(heap) > 0:
            popped = hq.heappop(heap).list_node 
            tail.next = popped
            if popped.next:
                hq.heappush(heap, HeapNode(popped.next)) 

        return head


#try creating a wrapper class for the heap node, to override the comparison method
class HeapNode:
    def __init__(self, list_node):
        self.list_node = list_node
        self.next = list_node.next
        self.priority = list_node.val
# override the comparison operator
    def __lt__(self, nxt):
        if self.priority == nxt.priority:
            return self.next.val < nxt.next.val
        else:
            return self.priority < nxt.priority
    def __str__(self):
        return f'[Priority: {self.priority}, Next Node Val: {self.next.val}]'

Outputs: STDOUT:

len of heap:  3
heap[0]:  [Priority: 1, Next Node Val: 3]
len of heap:  0

ERROUT:

IndexError: list index out of range
    print("heap[0]: ", heap[0])
Line 30 in mergeKLists (Solution.py)
    ret = Solution().mergeKLists(param_1)
Line 79 in _driver (Solution.py)
    _driver()
Line 90 in <module> (Solution.py)

0 Answers0