diff --git a/0143.Reorder-List/memo.md b/0143.Reorder-List/memo.md new file mode 100644 index 0000000..cbea894 --- /dev/null +++ b/0143.Reorder-List/memo.md @@ -0,0 +1,32 @@ +# 143. Reorder List + +## step1 +まずlistを使った方法を書いてみる。5mほど。これでは解けたことにならなそうなのでポインタのみを使って計算量を抑えたい。 + +Discussionの以下を見て解法を思いついた。後半を reverse すればいけそう。ヒントなしで解法には辿り着けなかった。 + +> Good practice for most of the important techniques of dealing with linked lists, ie. 2 pointer traversing, reversing, merging, ... + +ここまで17mほど。変数名を改善 + +## 他の人のコード + +https://github.com/thonda28/leetcode/pull/4 + +> ノード数が偶数のとき、真ん中のノードは、左半分の最後と右半分の最初の二つありますよね。どっちを返すかコメントに書いた方が分かりやすいです。 + +たしかに + +- front, back, interleaveの命名 + +自分のformer, latterでもよいとは思った + + +> 最初からなるべく(ちょうどいい粒度の)関数に分けた方がいいのではないでしょうか?普段コードを書く時も、全てのコードをメイン関数に書いてから、関数化したりしないですよね。 + +関数化しようと思わなかったのは反省すべきなのかもしれない + +https://github.com/potrue/leetcode/pull/68 + +## step2 +## step3 diff --git a/0143.Reorder-List/step1_list.py b/0143.Reorder-List/step1_list.py new file mode 100644 index 0000000..9c478af --- /dev/null +++ b/0143.Reorder-List/step1_list.py @@ -0,0 +1,27 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reorderList(self, head: Optional[ListNode]) -> None: + if head is None: + return + + ordered_list = [] + node = head + while node is not None: + ordered_list.append(node) + node = node.next + + left = 0 + right = len(ordered_list) - 1 + while left < right: + ordered_list[left].next = ordered_list[right] + left += 1 + if left == right: + break + ordered_list[right].next = ordered_list[left] + right -= 1 + + ordered_list[left].next = None diff --git a/0143.Reorder-List/step1_two_pointer.py b/0143.Reorder-List/step1_two_pointer.py new file mode 100644 index 0000000..fe5dd92 --- /dev/null +++ b/0143.Reorder-List/step1_two_pointer.py @@ -0,0 +1,35 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reorderList(self, head: Optional[ListNode]) -> None: + if head is None: + return + + slow = head + fast = head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + original_latter = slow.next + slow.next = None + node = None + + while original_latter is not None: + temp = original_latter.next + original_latter.next = node + node = original_latter + original_latter = temp + + original_former = head + original_latter = node + while original_former is not None and original_latter is not None: + next_former = original_former.next + next_latter = original_latter.next + original_former.next = original_latter + original_latter.next = next_former + original_former = next_former + original_latter = next_latter diff --git a/0143.Reorder-List/step1_two_pointer_revised.py b/0143.Reorder-List/step1_two_pointer_revised.py new file mode 100644 index 0000000..5c34f70 --- /dev/null +++ b/0143.Reorder-List/step1_two_pointer_revised.py @@ -0,0 +1,35 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reorderList(self, head: Optional[ListNode]) -> None: + if head is None: + return + + slow = head + fast = head + while fast is not None and fast.next is not None: + slow = slow.next + fast = fast.next.next + + latter = slow.next + slow.next = None + node = None + + while latter is not None: + next_latter = latter.next + latter.next = node + node = latter + latter = next_latter + + former = head + latter = node + while former is not None and latter is not None: + next_former = former.next + next_latter = latter.next + former.next = latter + latter.next = next_former + former = next_former + latter = next_latter diff --git a/0143.Reorder-List/step2.py b/0143.Reorder-List/step2.py new file mode 100644 index 0000000..462051f --- /dev/null +++ b/0143.Reorder-List/step2.py @@ -0,0 +1,47 @@ +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +class Solution: + def reorderList(self, head: ListNode | None) -> None: + if head is None: + return + + def find_middle(head: ListNode | None) -> ListNode | None: + # when the number of nodes is odd, the middle node is the left half of the list + # when the number of nodes is even, the middle node is the right half of the list + slow = head + fast = head + while fast is not None and fast.next is not None: + slow = slow.next + fast = fast.next.next + return slow + + middle = find_middle(head) + latter = middle.next + middle.next = None + + def reverse_list(head: ListNode | None) -> ListNode | None: + node = None + while head is not None: + next_head = head.next + head.next = node + node = head + head = next_head + return node + + reversed_latter = reverse_list(latter) + + def interleave(former: ListNode | None, latter: ListNode | None) -> None: + while former is not None and latter is not None: + next_former = former.next + next_latter = latter.next + former.next = latter + latter.next = next_former + former = next_former + latter = next_latter + + interleave(head, reversed_latter) diff --git a/0143.Reorder-List/step3.py b/0143.Reorder-List/step3.py new file mode 100644 index 0000000..31655ba --- /dev/null +++ b/0143.Reorder-List/step3.py @@ -0,0 +1,45 @@ +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +class Solution: + def reorderList(self, head: ListNode | None) -> None: + if head is None: + return + + def find_middle(head): + slow = head + fast = head + while fast is not None and fast.next is not None: + slow = slow.next + fast = fast.next.next + return slow + + middle = find_middle(head) + latter = middle.next + middle.next = None + + def reverse_list(head): + node = None + while head is not None: + next_head = head.next + head.next = node + node = head + head = next_head + return node + + reversed_latter = reverse_list(latter) + + def merge_lists(former, latter): + while former is not None and latter is not None: + next_former = former.next + next_latter = latter.next + former.next = latter + latter.next = next_former + former = next_former + latter = next_latter + + merge_lists(head, reversed_latter)