Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions week03/seoyoung.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# 3주차 문제 풀이 인증

## 기본 정보

- 이름: 이서영
- 목표 문제 수: 3
- 실제 풀이 문제 수: 3

## 푼 문제 목록

| 번호 | 문제 이름 | 난이도 | 링크 | 풀이 여부 |
| -- | ----- | ---- | ---------------------------------------------------------------- | ----- |
| 1 | 구명보트 | Lv.2 | https://school.programmers.co.kr/learn/courses/30/lessons/42885 | o |
| 2 | 순위 검색 | Lv.2 | https://school.programmers.co.kr/learn/courses/30/lessons/72412 | o |
| 3 | 호텔 대실 | Lv.2 | https://school.programmers.co.kr/learn/courses/30/lessons/155651 | o |

---

# 오답노트

> 오답노트는 AI 답변이나 블로그 풀이를 그대로 복사하지 않고, 본인의 언어로 직접 작성해주세요.
> 문제별로 아래 양식을 복사해서 필요한 만큼 반복 작성하시면 됩니다.

## 문제 1

### 문제 정보

* 문제명: 구명보트
* 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/42885
* 사용한 알고리즘 / 자료구조: Greedy, 투 포인터, 정렬

### 처음 접근 방식

몸무게가 가벼운 사람부터 두 명씩 묶어 보트에 태우려고 했다.

### 풀이 방법

1. 사람들의 몸무게를 오름차순으로 정렬한다.
2. 가장 가벼운 사람을 가리키는 `left`와 가장 무거운 사람을 가리키는 `right`를 설정한다.
3. 가장 가벼운 사람과 가장 무거운 사람의 무게 합이 제한 이하인지 확인한다.
4. 함께 탈 수 있다면 `left`와 `right`를 모두 이동한다.
5. 함께 탈 수 없다면 가장 무거운 사람만 태우고 `right`만 이동한다.
6. 보트를 사용할 때마다 보트 개수를 증가시킨다.

### 어려웠던 지점

왜 가장 무거운 사람과 가장 가벼운 사람을 먼저 비교해야 하는지 이해하기 어려웠다.

### 해결 방법

가장 무거운 사람이 가장 가벼운 사람과도 함께 탈 수 없다면 다른 누구와도 함께 탈 수 없으므로 혼자 태워야 한다.

함께 탈 수 있다면 가장 가벼운 사람과 묶어야 중간 몸무게의 사람들을 이후 조합에 활용할 수 있다.

### 시간복잡도 / 공간복잡도

* 시간복잡도: O(N log N)
* 공간복잡도: O(N)

### 새롭게 알게 된 점

최솟값을 구하는 문제에서는 매 순간 가장 불리한 대상부터 처리하는 Greedy 방식이 사용될 수 있다. 정렬된 배열의 양 끝을 비교할 때는 투 포인터를 사용하면 효율적이다.

---

## 문제 2

### 문제 정보

* 문제명: 순위 검색
* 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/72412
* 사용한 알고리즘 / 자료구조: 이분탐색, Hash Map, 정렬

### 처음 접근 방식

각 쿼리마다 모든 지원자 정보를 확인하면서 조건과 점수를 비교하려고 했다.

### 풀이 방법

1. 각 지원자의 언어, 직군, 경력, 음식 정보를 분리한다.
2. 각 조건을 실제 값 또는 `-`로 바꾼 16개의 조합을 생성한다.
3. 조건 조합을 문자열 키로 만들고 해당 지원자의 점수를 Hash Map의 리스트에 저장한다.
4. 모든 지원자의 정보를 저장한 뒤 각 점수 리스트를 오름차순으로 정렬한다.
5. 쿼리에서 `and`를 제거하고 조건과 기준 점수를 분리한다.
6. 쿼리 조건에 해당하는 점수 리스트를 찾는다.
7. 이분탐색으로 기준 점수 이상이 처음 나타나는 위치를 구한다.
8. 전체 리스트 길이에서 해당 위치를 빼 조건을 만족하는 지원자 수를 계산한다.

### 어려웠던 지점

각 쿼리마다 모든 지원자를 검사하면 정확성 테스트는 통과할 수 있지만 효율성 테스트에서 시간초과가 발생했다.

### 해결 방법

지원자 정보를 입력받을 때 `-`를 포함한 모든 조건 조합을 미리 만들어 저장했다.

각 조건에 해당하는 점수들을 정렬한 뒤, 쿼리마다 이분탐색을 사용해 기준 점수 이상의 지원자 수를 빠르게 계산했다.

### 시간복잡도 / 공간복잡도

* 시간복잡도: O(N log N + Q log N)
* 공간복잡도: O(N)

### 새롭게 알게 된 점

쿼리의 개수가 많을 때는 요청마다 전체 데이터를 검사하지 않고, 가능한 검색 조건을 미리 전처리하는 방식이 효율적이다.

정렬된 배열에서 특정 값 이상이 처음 등장하는 위치는 `bisect_left()`를 사용해 찾을 수 있다.

---

## 문제 3

### 문제 정보

* 문제명: 호텔 대실
* 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/155651
* 사용한 알고리즘 / 자료구조: 누적합, 차분 배열

### 처음 접근 방식

예약 시간을 시작 시간순으로 정렬하고, 각 방의 마지막 퇴실 시간을 저장하면서 사용할 수 있는 방을 찾으려고 했다.

### 풀이 방법

1. `"HH:MM"` 형식의 시각을 `시 × 60 + 분`으로 계산하여 분 단위 정수로 변환한다.
2. 하루의 각 분을 나타내는 배열을 생성한다.
3. 예약 시작 시각의 값을 1 증가시킨다.
4. 퇴실 시각에 청소 시간 10분을 더한 위치의 값을 1 감소시킨다.
5. 배열을 처음부터 순회하면서 이전 값과 현재 값을 누적한다.
6. 누적값은 해당 시각에 사용 중이거나 청소 중인 객실 수를 의미한다.
7. 누적값 중 최댓값을 필요한 최소 객실 수로 반환한다.

### 어려웠던 지점

퇴실 직후 바로 방을 다시 사용할 수 없고, 청소 시간 10분까지 객실을 사용 중인 것으로 처리해야 했다.

### 해결 방법

퇴실 시각이 아니라 `퇴실 시각 + 10분` 위치에서 사용 객실 수를 감소시켰다.

예를 들어 10시 10분에 퇴실하면 10시 20분부터 해당 객실을 다시 사용할 수 있도록 처리했다.

### 시간복잡도 / 공간복잡도

* 시간복잡도: O(N + T)
* 공간복잡도: O(T)

`T`는 분 단위로 표현한 전체 시간 범위이며 약 1,450이다.

### 새롭게 알게 된 점

구간이 시작되는 위치에 1을 더하고 끝나는 위치에 1을 빼는 차분 배열을 만든 뒤 누적합을 계산하면, 각 시점에 겹치는 구간의 개수를 효율적으로 구할 수 있다.

---

# 다음 주 목표

* 목표 문제 수: 3
* 집중할 유형: DFS / BFS