August 10, 2021
정렬되어 있는 두 연결 리스트를 병합하고 정렬하여 반환하라
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
Input: l1 = [], l2 = []
Output: []
Input: l1 = [], l2 = [0]
Output: [0]
ListNode{val: 0, next: None}
ListNode{val: 0, next: None}
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
rev = ListNode()
res = rev
while l1 and l2:
if l1.val < l2.val:
res.next = l1
l1 = l1.next
else:
res.next = l2
l2 = l2.next
res = res.next
res.next = l1 if l1 else l2
return rev.next
rev
에 ListNode
클래스 인스턴스를 생성해주고 이를 res
가 참조한다. l1
과 l2
가 None
이 될때가지 반복을 돌려주고 l1
과 l2
를 비교하여 l1
이 작다면 res
의 다음 노드(res.next
)에 l1
을 할당하고 l1
을 다음 노드로 이동시켜 준다.
만약 l2
가 작다면 rex
의 다음 노드에 l2
를 할당하고 l2
를 다음 노드로 이동시켜준다. 비교 과정이 끝나면 res
를 다음 노드로 이동 시켜 주고 이를 반복한다.
l1
과 l2
모두 끝 지점까지 도달하였으면 반복을 종료하고 res
의 다음 노드에 l1
또는 l2
의 나머지를 연결 하고 res
가 참조하고 있는 rev
의 next
를 리턴해준다.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(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.mergeTwoLists(l1.next, l2)
return l1
먼저 l1
의 None
이 아니거나 l2
가 None
이 아니면서 l1
의 값이 l2
의 값보다 작을때 l1
과 l2
변수를 스왑한다. 이후에 l1
이 None
이 아니라면서 l1
의 next
를 재귀호출하면서 다음번 연결 리스트가 계속 스왑될 수 있게 한다.
이렇게 스왑하면서 그 다음 값이 엮이도록 계속 재귀호출 하면 연결 리스트가 점점 하나로 병합된다. 마지막에는 l1
이 None
이 되면서 재귀가 끝나고 리턴을 시작한다.
우선순위 | 연산자 | 설명 |
---|---|---|
1 | () | 괄호 |
2 | f(args...) | 함수 호출 |
3 | x[index:index] | 슬라이싱 |
4 | x[index] | 배열 |
5 | x.attribute | 속성 참조 |
6 | ** | 지수 |
7 | ~x | 비트 연산 NOT |
8 | +x , -x | 양수, 음수 |
9 | * , / , % | 곱, 나눗셈, 나머지 |
10 | + , - | 덧셈, 뺄셈 |
11 | << , >> | 비트 연산 시프트 |
12 | & | 비트 연산 AND |
13 | ^ | 비트 연산 XOR |
14 | | | 비트 연산 OR |
15 | in , not in , is , is not , < , ≤ , > , ≥ , <> , ≠ , == | 비교 연산 |
16 | not x | Bool 연산 NOT |
17 | and | Bool 연산 AND |
18 | or | Bool 연산 OR |
19 | lambda | 람다 표현 |
두 변수를 스왑하는 가장 일반적이고 널리 사용되는 방법은 임시 변수를 사용하는 방법이다.
temp = a
a = b
b = temp
이 방식은 거의 모든 언어에서 사용할 수 있는 가장 기본적인 방식이다. 그러나 Python에서는 다중 할당을 통해 이 변수 스왑이 가능하며 가독성 또한 좋아 별다른 이슈가 없는 한 이 방식으로 스왑하는게 가장 좋다.
a: int = 1
b: int = 2
a, b = b, a
숫자형인 경우 간단한 덧셈, 뺄셈을 통해 임시 변수 없이 스왑을 할 수 있는 방법이 있고 다음과 같이 가능하다.
x += y
y = x - y
x -= y
여기서 만약 입력값이 x=9
, y=4
라고 가정한다면 결과는 다음과 같다.
x += y
의 결과 x=13
y = x -y
의 결과 y=9
x -= y
의 결과 x=4
>>> x = 9
>>> y = 4
>>> x += y
>>> y = x-y
>>> x -= y
>>> x
4
>>> y
9
이 방식은 추가 공간을 필요로 하지 않는다는 점에서 공간 복잡도 또한 필요하지 않은 좋은 방법이나 숫자여야 하는 등의 제약사항으로 실용적인 면은 다소 부족하다. 다만 간혹 오프라인 인터뷰에서 이런 질문이 나오기도 하여 알아둘 필요는 있다.