diff --git a/missing-number/KwonNayeon.py b/missing-number/KwonNayeon.py index 2a9820a9f..4a32c7445 100644 --- a/missing-number/KwonNayeon.py +++ b/missing-number/KwonNayeon.py @@ -5,24 +5,29 @@ 3. Each element nums[i] is between 0 and n inclusive 4. All numbers in nums are unique (no duplicates) + Time Complexity: O(nlogn) - - 정렬에 nlogn, 순회에 n이 필요하므로 전체적으로 O(nlogn) +- 정렬에 nlogn, 순회에 n이 필요하므로 전체적으로 O(nlogn) + Space Complexity: O(1) - - 추가 공간을 사용하지 않고 입력 배열만 사용 +- 추가 공간을 사용하지 않고 입력 배열만 사용 풀이 방법: - 1. 배열을 정렬하여 0부터 n까지 순서대로 있어야 할 위치에 없는 숫자를 찾음 - 2. 인덱스와 해당 위치의 값을 비교하여 다르다면 그 인덱스가 missing number - 3. 모든 인덱스를 확인했는데도 없다면 n이 missing number +1. nums 배열을 오름차순으로 정렬 +2. 0부터 n-1까지 순서대로 비교하여 인덱스와 다른 값을 찾음 + - 인덱스와 해당 위치의 값이 일치하지 않을 때, 그 인덱스가 missing number """ - class Solution: def missingNumber(self, nums: List[int]) -> int: + n = len(nums) nums.sort() - for i in range(len(nums)): - if nums[i] != i: + for i in range(n): + if i == nums[i]: + continue + else: return i - - return len(nums) + # missing number가 배열의 마지막에 오는 경우 + return n + diff --git a/reorder-list/KwonNayeon.py b/reorder-list/KwonNayeon.py index 21d57255a..7fe58828e 100644 --- a/reorder-list/KwonNayeon.py +++ b/reorder-list/KwonNayeon.py @@ -7,18 +7,21 @@ - 리스트를 한 번씩 순회하면서 알고리즘의 각 단계를 수행함 Space Complexity: O(1) -- 정해진 개수의 변수 외에는 추가 공간을 사용하지 않음 +- 정해진 변수 외에는 추가 공간을 사용하지 않음 풀이방법: 1. 중간 지점 찾기 - - slow/fast 포인터를 사용하여 중간 지점 찾기 +- slow/fast 포인터를 사용하여 중간 지점 찾기 2. 뒷부분 뒤집기 - - prev, curr 포인터로 링크드 리스트의 방향 전환 - - next_temp에 다음 노드를 저장한 후 방향 변경 +- prev, curr 포인터로 링크드 리스트의 방향 전환 +- next_temp에 다음 노드를 저장한 후 방향 변경 3. 앞부분과 뒷부분 합치기 - - 두 리스트의 시작점(first, second)부터 시작 - - temp1, temp2에 다음 노드 저장 - - 포인터들을 번갈아가며 연결함 +- 두 리스트의 시작점(first, second)부터 시작 +- temp1, temp2에 다음 노드 저장 +- 포인터들을 번갈아가며 연결함 + +노트: +- 포인터 조작(연결리스트 뒤집기, 병합) 방법을 다 까먹어서 복습용 예시 주석을 추가해둠 """ # Definition for singly-linked list. # class ListNode: @@ -27,37 +30,61 @@ # self.next = next class Solution: def reorderList(self, head: Optional[ListNode]) -> None: - """ - Do not return anything, modify head in-place instead. - """ - # 중간 지점 찾기 - slow = head - fast = head + # 초기 상태: 1->2->3->4->5 + + # 1단계: 중간 지점 찾기 + slow = head # slow = 1 + fast = head # fast = 1 while fast and fast.next: - slow = slow.next - fast = fast.next.next - - # 뒷부분 뒤집기 - prev = None - curr = slow.next - slow.next = None + slow = slow.next # slow: 1->2->3 + fast = fast.next.next # fast: 1->3->5->None + # 결과: slow는 3에 위치 + + # 2단계: 뒷부분 뒤집기 + prev = None # prev = None + curr = slow.next # curr = 4 (뒷부분 시작점) + slow.next = None # 분리: 1->2->3 | 4->5 + while curr: - next_temp = curr.next - curr.next = prev - prev = curr - curr = next_temp + # 1회전: curr=4, prev=None + next_temp = curr.next # next_temp = 5 + curr.next = prev # 4->None + prev = curr # prev = 4 + curr = next_temp # curr = 5 + # 상태: 1->2->3 | 4->None, curr=5 - # 앞부분과 뒷부분 합치기 - first = head - second = prev + # 2회전: curr=5, prev=4 + next_temp = curr.next # next_temp = None + curr.next = prev # 5->4 + prev = curr # prev = 5 + curr = next_temp # curr = None (종료) + # 상태: 1->2->3 | 5->4->None + + # 3단계: 앞부분과 뒷부분 합치기 + first = head # first = 1->2->3 + second = prev # second = 5->4 + while second: - temp1 = first.next - temp2 = second.next + # 1회전: first=1, second=5 + temp1 = first.next # temp1 = 2 + temp2 = second.next # temp2 = 4 - first.next = second - second.next = temp1 + first.next = second # 1->5 + second.next = temp1 # 5->2 + # 현재 상태: 1->5->2->3, 남은 second = 4 - first = temp1 - second = temp2 - - + first = temp1 # first = 2 + second = temp2 # second = 4 + + # 2회전: first=2, second=4 + temp1 = first.next # temp1 = 3 + temp2 = second.next # temp2 = None + + first.next = second # 2->4 + second.next = temp1 # 4->3 + # 현재 상태: 1->5->2->4->3 + + first = temp1 # first = 3 + second = temp2 # second = None (종료) + + # 최종 결과: 1->5->2->4->3