-
-
Notifications
You must be signed in to change notification settings - Fork 361
[okyungjin] WEEK 04 Solutions #2743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
276ce10
f245112
ea4170f
441ac50
d77d59d
9afa0f2
e65811c
b5c8317
6808c86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
okyungjin marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 둘 다 선형 시간복잡도로 병합하며, 메모리 사용은 노드 재사용 여부에 따라 달라진다. 개선 제안: 현재 구현이 적절해 보입니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # from typing import Optional, List | ||
|
|
||
| # class ListNode: | ||
| # def __init__(self, val=0, next=None): | ||
| # self.val = val | ||
| # self.next = next | ||
|
|
||
| # # 파이썬의 toString 역할을 하는 __repr__을 [1,3,4] 형태로 출력되게 수정 | ||
| # def __repr__(self): | ||
| # nodes = [] | ||
| # curr = self | ||
| # while curr: | ||
| # nodes.append(str(curr.val)) | ||
| # curr = curr.next | ||
| # return "[" + ",".join(nodes) + "]" | ||
|
|
||
| # # 파이썬 list를 ListNode 리스트로 변환해주는 헬퍼 함수 | ||
| # def make_linked_list(arr: List[int]) -> Optional[ListNode]: | ||
| # if not arr: | ||
| # return None | ||
| # dummy = ListNode(0) | ||
| # curr = dummy | ||
| # for val in arr: | ||
| # curr.next = ListNode(val) | ||
| # curr = curr.next | ||
| # return dummy.next | ||
|
|
||
|
|
||
| # list1의 노드 개수를 n, list2의 노드 개수를 m이라 할 때 | ||
| # 시간 복잡도: O(n + m) | ||
| # 공간 복잡도: O(n + m) -> | ||
| class Solution_01: | ||
| def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: | ||
| # 맨 앞에 더미 노드를 하나 추가한다 | ||
| # 없는 상태로 짰는데 if node: else: 구문 늘어나서 맨 앞에 가상의 노드를 하나 추가해줬다 | ||
| dummy = ListNode(None) | ||
| node = dummy | ||
|
|
||
| while True: | ||
| # list1이 비어있으면 현재 노드 뒤로 list2를 이어준다. | ||
| if not list1: | ||
| node.next = list2 | ||
| break | ||
|
|
||
| # list2가 비어있으면 현재 노드 뒤로 list1을 이어준다. | ||
| if not list2: | ||
| node.next = list1 | ||
| break | ||
|
|
||
| # 값을 비교해서 작은 값을 next 노드에 추가한다. | ||
| if list1.val <= list2.val: | ||
| node.next = ListNode(list1.val) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에서 ListNode(list1.val)로 매번 새 노드를 생성하시는데, 기존 노드를 그대로 연결(node.next = list1)하면 새 노드를 안 만들어도 돼서 공간 복잡도를 O(1)로 줄일 수 있을 것 같아요. 저는 그렇게 풀었는데 참고하시라고 남깁니다! 전체 로직은 깔끔하게 잘 읽혔어요 👍
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @chapse57 코멘트 감사합니다! 풀이를 2가지로 작성했는데 이 부분 언급해주신게 맞을까요? |
||
| # list1 하나 소비 | ||
| list1 = list1.next | ||
| else: | ||
| node.next = ListNode(list2.val) | ||
| # list2 하나 소비 | ||
| list2 = list2.next | ||
|
|
||
| # 다음 노드를 현재 노드로 할당해준다 | ||
| node = node.next | ||
|
|
||
| return dummy.next | ||
|
|
||
|
|
||
| # [접근법] Solution_01 의 공간 복잡도를 개선했습니다. | ||
| # ListNode를 새로 생성하지 않고 기존 노드를 활용하도록 수정했습니다. | ||
|
|
||
| # list1의 노드 개수를 n, list2의 노드 개수를 m이라 할 때 | ||
| # 시간 복잡도: O(n + m) | ||
| # 공간 복잡도: O(1) -> dummy만 사용, 추가 공간 복잡도는 O(1) | ||
| class Solution_01: | ||
| def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: | ||
| # 맨 앞에 더미 노드를 하나 추가한다 | ||
| # 없는 상태로 짰는데 if node: else: 구문 늘어나서 맨 앞에 가상의 노드를 하나 추가해줬다 | ||
| dummy = ListNode(None) | ||
| node = dummy | ||
|
|
||
| while True: | ||
| if not list1: # list1이 비어있으면 현재 노드 뒤로 list2를 이어준다. | ||
| node.next = list2 | ||
| break | ||
|
|
||
| if not list2: # list2가 비어있으면 현재 노드 뒤로 list1을 이어준다. | ||
| node.next = list1 | ||
| break | ||
|
|
||
| # 값을 비교해서 작은 값을 next 노드에 추가한다. | ||
| if list1.val <= list2.val: | ||
| node.next = list1 # 새로운 ListNode를 생성하지 않고 list1를 할당해준다. | ||
| list1 = list1.next # list1 하나 소비 | ||
| else: | ||
| node.next = list2 # 새로운 ListNode를 생성하지 않고 list2를 할당해준다. | ||
| list2 = list2.next # list2 하나 소비 | ||
|
|
||
| # 다음 노드를 현재 노드로 할당해준다 | ||
| node = node.next | ||
|
|
||
| return dummy.next | ||
|
|
||
|
|
||
| # 4. 예시 입력으로 호출 및 테스트 | ||
| # if __name__ == "__main__": | ||
| # list1 = make_linked_list([1, 2, 4]) | ||
| # list2 = make_linked_list([1, 3, 4]) | ||
|
|
||
| # solution = Solution() | ||
| # merged_list = solution.mergeTwoLists(list1, list2) | ||
|
|
||
| # print(merged_list) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DaleStudy 개선 제안: 더 나은 변수 네이밍과 주석 정리로 가독성을 높일 수 있습니다. 는 어떤 방식을 말하는건지 제안해주라
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋은 제안이에요. 더 나은 변수 네이밍과 주석 정리는 코드 가독성과 유지보수에 큰 도움이 됩니다. 아래 방식으로 구체적으로 제안드립니다.
원하는 방향으로 샘플 리팩틴 코드도 같이 드릴게요.