2주 차 회고 및 학습 전략 재정비
1. 알고리즘, 진짜 내 실력으로 다시 보기
이번 주 알고리즘 문제들을 해결했지만, 솔직히 AI의 도움을 많이 받았다. 그래서 오늘 아침, 교육장에 오자마자 이번 주에 풀었던 문제 목록을 쭉 훑어보며 '진짜 내 실력' 이 어느 정도인지 냉정하게 점검해 보기로 했다.
나만의 기준으로 문제별 숙련도를 1부터 5까지 매겼다.
- Lv. 5: 완벽 이해. 백지 상태에서 아이디어부터 최종 구현까지 막힘없이 가능.
- Lv. 3: 절반의 성공. 아이디어와 핵심 구현은 가능하지만, 디테일한 디버깅이나 엣지 케이스를 잡는 데 시간이 걸릴 것 같은 문제.
- Lv. 1: 아이디어만 희미하게. 어떻게 풀어야 할지 감은 오지만, 코드로 구현할 엄두가 나지 않는 문제.
이렇게 분류하고 숙련도가 낮은(Lv. 1) 문제부터 다시 풀어보니, 흩어져 있던 개념들이 정리되고 이번 주 학습 주제에 대한 이해도가 한층 깊어지는 것을 느낄 수 있었다.
2. '의식의 흐름'을 '시스템'으로 바꾸기 위한 시간표
"오늘 하루 뭐 했지?"
지금까지는 '하루'라는 큰 단위로만 시간을 사용했다. 그러다 보니 저녁에 TIL을 쓸 때면 막상 내가 뭘 했는지 기억이 잘 나지 않았고, '이건 오전에 해야지' 했던 일을 '저녁에 하자'며 미루는 일이 잦았다.
이런 **'의식의 흐름대로 공부하기'**를 멈추고자, Gemini에게 뇌과학 지식과 나의 생활 패턴을 알려주고 최적의 루틴을 추천받았다. 이 시간표를 내 상황에 맞게 조금 수정해서, 내일부터는 더 체계적인 하루를 살아보려 한다.
3. '모르겠다'의 원인 파고들기 및 지식 채우기
알고리즘 문제를 풀 때마다 아이디어를 떠올리거나, 아이디어를 코드로 구현하는 두 단계에서 계속 벽에 부딪혔다.
- 아이디어가 떠오르지 않는 문제: 이건 명백히 **'제반 지식 부족'**이라고 판단했다. 특정 유형에 대한 개념과 원리 이해가 부족하니 접근법 자체가 생각나지 않는 것이다. 이를 해결하기 위해 기본기를 다질 수 있는 강의를 찾아 다시 듣고 있다.
- 구현이 막히는 문제: 이 부분은 이전에 커피챗에서 얻은 조언처럼, '경험의 차이'와 '기술 숙련도' 의 문제라고 생각한다. 머릿속 아이디어를 코드로 빠르고 정확하게 번역하는 훈련이 필요한 것이다. 앞으로 다양한 문제를 풀어보며 코드 구현력을 꾸준히 쌓아갈 계획이다. 하학적 문제를 1차원 문제로 변환하여 생각하는 관점이 인상적이었다.
오늘의 학습 노트 📝
오늘 알고리즘 문제를 풀면서 계속 발목을 잡던 개념 두 가지를 집중적으로 파고들었다. '어떻게' 푸는지에만 매몰되지 않고, '왜' 이렇게 작동하는지 원리를 이해하는 데 초점을 맞췄다.
1. 파이썬 enumerate()
무엇을 배웠나?
enumerate는 파이썬의 내장 함수로, for 루프를 사용할 때 리스트나 튜플 같은 순회 가능한(iterable) 객체의 인덱스(index)와 값(value)을 하나의 튜플로 묶어서 반환해 준다.
왜 유용한가?
기존에는 for문을 돌리면서 현재 요소가 "몇 번째"인지 확인하려면, 아래와 같이 별도의 index 변수를 선언하고 루프가 돌 때마다 +1을 해줘야 했다.
# Before
fruits = ['apple', 'banana', 'cherry']
index = 0
for fruit in fruits:
if index % 2 == 0: # 짝수 번째 과일만 출력
print(f"{index}: {fruit}")
index += 1이 방식은 코드가 길어지고, index 변수를 따로 관리해야 하는 번거로움이 있다. 하지만 enumerate를 사용하면 이 모든 과정이 단 한 줄로 해결된다.
# After
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
if index % 2 == 0:
print(f"{index}: {fruit}")for index, fruit in enumerate(fruits): 구문이 enumerate 객체에서 (0, 'apple'), (1, 'banana'), (2, 'cherry') 같은 튜플을 순서대로 꺼내와 index와 fruit 변수에 자동으로 할당해 준다. 훨씬 직관적이고 파이썬다운 코드다.
start=1 옵션을 주면 인덱스를 1부터 시작할 수도 있어서, 실제 순번을 다룰 때 매우 편리하다.
2. 스위핑(Sweeping) 알고리즘
무엇을 배웠나?
스위핑(Sweeping) 은 여러 선분이나 도형이 겹치는 복잡한 기하학 문제를 해결하기 위한 알고리즘이다. 문제의 공간을 특정 축(주로 x축)을 기준으로 정렬한 뒤, **'스위프 라인(Sweep Line)'**이라는 가상의 선을 한쪽 끝에서부터 다른 쪽 끝까지 이동시키며 **'이벤트 포인트'**에서만 계산을 수행하는 방식이다.
핵심 아이디어
- 차원 축소: 2차원 평면 문제를 1차원 직선 문제처럼 바꾼다.
- 이벤트 포인트: 계산이 필요한 지점을 미리 정의한다. (예: 선분의 시작점, 끝점, 원의 왼쪽/오른쪽 끝)
- 정렬: 모든 이벤트 포인트를 x좌표 기준으로 정렬하는 것이 가장 중요하다.
- 상태 관리: 스위프 라인이 이동하면서 만나는 이벤트에 따라, 현재 상태(예: 겹치는 선분의 개수)를 자료구조(스택, 우선순위 큐 등)를 이용해 업데이트한다.
왜 강력한가?
백준 10000번 '원 영역' 문제처럼, 수많은 원들이 어떻게 겹쳐있는지 모든 쌍을 비교하는 것은 비효율적이다(O(N²)). 하지만 스위핑을 사용하면, 각 원의 '왼쪽 끝(시작 이벤트)'과 '오른쪽 끝(종료 이벤트)'만 신경 쓰면 된다.
스위프 라인이 왼쪽에서 오른쪽으로 이동하면서,
- 원의 왼쪽 끝을 만나면 → "새로운 원이 시작되었구나!" (스택에 push)
- 원의 오른쪽 끝을 만나면 → "방금 지나온 원이 끝났구나!" (스택에서 pop)
이처럼 이벤트가 발생하는 특정 지점에서만 상태를 갱신하면 되므로, 전체적인 시간 복잡도를 O(N log N) (정렬 시간)으로 크게 줄일 수 있다. 복잡한 문제를 단순한 이벤트의 흐름으로 바꿔 생각하는 관점이 가장 중요하다고 느꼈다.