From ed17067f8558963f17b648896a5166e163b7567d Mon Sep 17 00:00:00 2001 From: shining-ai Date: Thu, 23 May 2024 18:02:27 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=E3=80=90Grind75Hard=E3=80=918=E5=95=8F?= =?UTF-8?q?=E7=9B=AE=2023.=20Merge=20k=20Sorted=20Lists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../08_23_Merge k Sorted Lists/level_1.py | 40 +++++++++++++++++++ .../08_23_Merge k Sorted Lists/level_2.py | 19 +++++++++ .../08_23_Merge k Sorted Lists/level_3.py | 18 +++++++++ 3 files changed, 77 insertions(+) create mode 100644 grind75_hard/08_23_Merge k Sorted Lists/level_1.py create mode 100644 grind75_hard/08_23_Merge k Sorted Lists/level_2.py create mode 100644 grind75_hard/08_23_Merge k Sorted Lists/level_3.py 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 From 276a171493d08589bd18d38a7f18bbffacc0c836 Mon Sep 17 00:00:00 2001 From: shining-ai Date: Fri, 24 May 2024 09:11:46 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E6=96=B0=E3=81=97=E3=81=84=E3=83=8E?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=82=92=E4=BD=9C=E3=82=89=E3=81=9A=E3=80=81?= =?UTF-8?q?=E3=81=A4=E3=81=AA=E3=81=8E=E7=9B=B4=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../08_23_Merge k Sorted Lists/level_4.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 grind75_hard/08_23_Merge k Sorted Lists/level_4.py 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..1792d47 --- /dev/null +++ b/grind75_hard/08_23_Merge k Sorted Lists/level_4.py @@ -0,0 +1,19 @@ +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 From d790cb6f99c28617860a91d6e823fce0acaadf0b Mon Sep 17 00:00:00 2001 From: shining-ai Date: Fri, 24 May 2024 15:45:01 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=E3=83=9E=E3=83=BC=E3=82=B8=E3=82=BD?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=82=92=E3=82=A4=E3=83=A1=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=81=97=E3=81=9F=E8=A7=A3=E6=B3=95=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../08_23_Merge k Sorted Lists/level_4.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) 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 index 1792d47..817c577 100644 --- a/grind75_hard/08_23_Merge k Sorted Lists/level_4.py +++ b/grind75_hard/08_23_Merge k Sorted Lists/level_4.py @@ -17,3 +17,36 @@ def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: 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)