diff --git a/grind75_hard/08_23_Merge k Sorted Lists/level_1.py b/grind75_hard/08_23_Merge k Sorted Lists/level_1.py new file mode 100644 index 0000000..fce678b --- /dev/null +++ b/grind75_hard/08_23_Merge k Sorted Lists/level_1.py @@ -0,0 +1,40 @@ +# 要素を全て入れて、sortしてからlinked listに変換 +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + lists_val = [] + for node in lists: + while node: + lists_val.append(node.val) + node = node.next + lists_val.sort() + sentinel = ListNode() + node = sentinel + for i in lists_val: + node.next = ListNode(i) + node = node.next + + return sentinel.next + + +# 各linked listの先頭を比較していく +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + sentinel = ListNode() + node = sentinel + while lists: + min_val = float("inf") + for i in range(len(lists)): + if not lists[i] or lists[i].val > min_val: + continue + min_val = lists[i].val + min_index = i + if min_val == float("inf"): + break + node.next = ListNode(min_val) + node = node.next + min_node = lists.pop(min_index) + min_node = min_node.next + if min_node: + lists.append(min_node) + + return sentinel.next diff --git a/grind75_hard/08_23_Merge k Sorted Lists/level_2.py b/grind75_hard/08_23_Merge k Sorted Lists/level_2.py new file mode 100644 index 0000000..adcb97b --- /dev/null +++ b/grind75_hard/08_23_Merge k Sorted Lists/level_2.py @@ -0,0 +1,19 @@ +# heapqに先頭の値だけを入れていく +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + min_heap = [] + for i, node in enumerate(lists): + if not node: + continue + heapq.heappush(min_heap, (node.val, i, node)) + sentinel = ListNode() + node = sentinel + while min_heap: + val, index, smallest_head = heapq.heappop(min_heap) + node.next = ListNode(val) + node = node.next + if smallest_head.next: + heapq.heappush( + min_heap, (smallest_head.next.val, index, smallest_head.next) + ) + return sentinel.next diff --git a/grind75_hard/08_23_Merge k Sorted Lists/level_3.py b/grind75_hard/08_23_Merge k Sorted Lists/level_3.py new file mode 100644 index 0000000..e469809 --- /dev/null +++ b/grind75_hard/08_23_Merge k Sorted Lists/level_3.py @@ -0,0 +1,18 @@ +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + min_heap = [] + for i, node in enumerate(lists): + if not node: + continue + heapq.heappush(min_heap, (node.val, i, node)) + sentinel = ListNode() + node = sentinel + while min_heap: + val, index, smallest_head = heapq.heappop(min_heap) + node.next = ListNode(val) + node = node.next + if smallest_head.next: + heapq.heappush( + min_heap, (smallest_head.next.val, index, smallest_head.next) + ) + return sentinel.next diff --git a/grind75_hard/08_23_Merge k Sorted Lists/level_4.py b/grind75_hard/08_23_Merge k Sorted Lists/level_4.py new file mode 100644 index 0000000..817c577 --- /dev/null +++ b/grind75_hard/08_23_Merge k Sorted Lists/level_4.py @@ -0,0 +1,52 @@ +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + min_heap = [] + for i, node in enumerate(lists): + if not node: + continue + # node.valが同値の場合にListNodeで比較しないようにindexをheapに追加 + heapq.heappush(min_heap, (node.val, i, node)) + sentinel = ListNode() + node = sentinel + while min_heap: + val, index, smallest_head = heapq.heappop(min_heap) + node.next = smallest_head + node = node.next + if smallest_head.next: + heapq.heappush( + min_heap, (smallest_head.next.val, index, smallest_head.next) + ) + return sentinel.next + + +# マージソートをイメージした解法 +# 先頭の2つのリストをマージしていき、最後の1つになるまで繰り返す +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + def merge_two_lists(list_1, list_2): + sentinel = ListNode() + node = sentinel + while list_1 and list_2: + if list_1.val < list_2.val: + node.next = list_1 + list_1 = list_1.next + else: + node.next = list_2 + list_2 = list_2.next + node = node.next + if not list_1: + node.next = list_2 + else: + node.next = list_1 + return sentinel.next + + list_queue = deque(lists) + if not list_queue: + return None + while 1: + list_1 = list_queue.popleft() + if not list_queue: + return list_1 + list_2 = list_queue.popleft() + mearged_list = merge_two_lists(list_1, list_2) + list_queue.append(mearged_list)