프로그래밍/코딩 테스트, 더 이상 미룰 수 없다

[코딩 테스트, 더 이상 미룰 수 없다] 프로그래머스 Lv1 - 신고 결과 받기

d 0_0 b 2026. 6. 26. 13:03

 

 

Python 자료구조를 어떻게 활용하면 코드를 더 간결하게 만들 수 있는지를 배우는 문제였다.

1. 중복 제거는 set()

처음에는 신고 내역을 그대로 순회했지만, 같은 사람이 같은 사람을 여러 번 신고할 수 있다는 조건이 있었다.

이 조건은 직접 중복을 검사하기보다 처음부터

for pair in set(report):

처럼 set()으로 변환해 중복을 제거하는 것이 훨씬 간단했다.

앞으로도 중복 제거가 필요한 입력이라면 가장 먼저 set()을 떠올리는 습관을 가져가려고 한다.


2. defaultdict(list)

기존에는 Dictionary에 값을 넣기 전에

if key not in dict:
    dict[key] = []

처럼 리스트를 먼저 생성해야 했다.

이번에는

from collections import defaultdict

report_dict = defaultdict(list)

를 사용하면서

report_dict[reported].append(report)

만으로 바로 리스트를 사용할 수 있다는 것을 알게 되었다.

defaultdict를 사용하면 초기화 코드를 줄일 수 있고, 구현 문제에서 실수를 줄일 수 있다는 점이 인상적이었다.


3. 이름을 인덱스로 변환하는 Dictionary

이번 문제에서 가장 새롭게 배운 부분이다.

처음에는

id_list.index(name)

로 answer의 위치를 찾으려고 했다.

하지만 index()는 호출할 때마다 리스트를 처음부터 탐색하기 때문에 비효율적이다.

대신 처음에 한 번만

name_to_index = {}

for index, name in enumerate(id_list):
    name_to_index[name] = index

를 만들어 두면

answer[name_to_index[name]] += 1

처럼 바로 접근할 수 있다.

앞으로 문자열이나 ID를 배열의 위치로 자주 찾아야 하는 문제라면, 처음부터 "이름 → 인덱스" Dictionary를 만드는 것을 먼저 생각하려고 한다.


4. enumerate() 활용

이번 문제에서 자연스럽게 enumerate()도 익숙해졌다.

for index, name in enumerate(id_list):

처럼 사용하면 인덱스와 값을 동시에 가져올 수 있어 따로 변수를 관리할 필요가 없다.

리스트를 순회하면서 인덱스가 필요한 상황에서는 앞으로 기본적으로 사용할 것 같다.


5. 문제를 자료구조로 먼저 표현하기

이번 문제의 핵심은 구현보다 데이터를 어떻게 저장할지였다.

최종적으로는

신고당한 사람
        ↓
신고한 사람들(List)

형태로 저장했다.

예를 들면

frodo → [muzi, apeach]
neo → [frodo]

처럼 구성한 뒤,

신고 횟수가 k 이상인 사람을 찾아 신고자들의 메일 수를 증가시키는 흐름으로 구현했다.

문제를 읽자마자 코드를 작성하기보다 "어떤 자료구조로 표현하면 가장 자연스러울까?"를 먼저 고민하는 것이 구현 문제에서는 더 중요하다는 점을 느꼈다.


이번 문제 복습 포인트

  • 중복 제거가 필요하면 set()을 먼저 떠올리기
  • defaultdict(list)를 활용해 Dictionary 초기화 코드 줄이기
  • enumerate()로 인덱스와 값을 동시에 가져오기
  • index()를 반복 호출하지 말고 이름 → 인덱스 Dictionary를 먼저 만들기
  • 구현 전에 데이터를 어떤 형태로 저장할지 먼저 설계하기

이번 문제는 알고리즘보다 Python 자료구조를 어떻게 활용하는지가 훨씬 중요한 문제였다. 앞으로 구현 문제를 풀 때도 코드를 작성하기 전에 필요한 자료구조부터 먼저 설계하는 습관을 가져가려고 한다.