“파이썬 알고리즘 인터뷰” + https://leetcode.com/problems/merge-two-sorted-lists/submissions/
당분간 연결 리스트를 이용한 문제다. 오늘은 정렬된 연결 리스트다.
class Solution:
def mergeTwoLists1(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
if not l1 or (l2 and l1.val > l2.val):
l1, l2 = l2, l1
if l1:
l1.next = self.mergeTwoLists1(l1.next, l2)
return l1
def mergeTwoLists2(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
lst1: List = self.convertToList(l1)
lst2: List = self.convertToList(l2)
concated = lst1 + lst2
concated.sort()
return self.createListNode(concated, 0)
def convertToList(self, ln: ListNode):
lst = []
node = ln
while node:
lst.append(node.val)
node = node.next
return lst
def createListNode(self, lst: List, index: int) -> ListNode:
if not lst:
return None
if index + 1 >= len(lst):
return ListNode(lst[index])
else:
return ListNode(lst[index], self.createListNode(lst, index + 1))
주어진 두 연결 리스트를 병합하되 정렬된 상태로 반환해야한다. 순간 그냥 리스트를 생각해서 왜 쉽지?라고 착각을 해버렸다. 그런데 리트코드 문제상에서 제약이 없다면 지난번처럼 연결 리스트를 파이썬 리스트로 바꿔서 + 연산해서 정렬한 결과를 연결 리스트로 만들어서 반환하는 것도 방법이겠다 싶어서 그렇게 했더니 에러 없이 통과돼서 난감했다. 그 코드가 mergeTwoList2()이다.
책에서 한 풀이는 mergeTwoList1()인데, 코드가 짧고 재귀로 되어 있어서 도통 이해가 안 된다. 연결 리스트 변화 과정을 따라 그려가면서 읽어도 대충 뭘 하는지는 알겠는데 마음으로 와닿지 않는 느낌?
아니면 내가 어렵게 접근해서 그럴 수도 있다. 그냥 두 연결 리스트의 노드를 각각 비교하는데, 스왑을 통해 작은 수를 한쪽 연결 리스트에 넣고 if not l1 or (l2 and l1.val > l2.val): l1, l2 = l2, l1
그 연결 리스트 노드의 넥스트에 넥스트 노드와 다른쪽을 비교해서 나온 결과를 할당하는 방식 l1.next = self.mergeTwoLists1(l1.next, l2)
으로 반복한다. …내가 적었지만 무슨 말인지 역시 모르겠다.
그냥 각각의 노드를 비교해서 작은 노드를 한쪽에 몰아넣는 방식인듯. 노드의 넥스트 노드가 자꾸 헷갈려서 문제지… 이번 문제는 다음에 다시 봐도 이해가 잘 안 될 것 같다.