시간은 쏜살같이 흘러, 어느덧 스프링 입문 3주차에 접어들었습니다. 이번 주에는 TODO 프로젝트를 진행하며, 웹 개발의 기초를 다지는 시간을 가졌습니다. 특히 STEP 2 '할 일 카드에 완료 여부 표시' 기능을 구현하면서, 예상치 못한 난관에 부딪히기도 하고, 새로운 도구를 발견하며 희열을 느끼기도 했습니다. 마치 파도를 헤쳐나가는 항해와 같은 한 주였죠.
삽질 끝에 만난 한 줄기 빛, PriorityQueue
이번 주차에 풀었던 알고리즘 문제 중 하나가 바로 '명예의 전당'이라는 문제였습니다. 간단히 설명하자면, 매일 발표되는 명예의 전당 목록에서 최하위 점수를 구하는 문제였죠. 처음에는 익숙한 sort, reverse, mutable 등의 방법을 동원하여 끙끙 앓았습니다. 코드를 수정하고, 테스트하고, 다시 수정하는 과정을 반복하면서 '이게 최선인가?'라는 의문이 계속 머릿속을 맴돌았습니다.
결국, 우여곡절 끝에 문제 풀이에 성공했지만, 다른 사람들의 풀이를 살펴보던 중 'PriorityQueue'라는 자료구조를 발견했습니다. 마치 사막에서 오아시스를 발견한 기분이었습니다.
PriorityQueue는 큐(Queue)와 유사하지만, 항목을 추가할 때 자동으로 오름차순 정렬을 해주는 놀라운 기능을 가지고 있습니다. 또한, peek() 메서드를 사용하면 맨 앞의 값(최솟값)을 쉽게 확인할 수 있고, poll() 메서드를 사용하면 최솟값을 반환하고 제거까지 해줍니다.
기존에 제가 풀었던 방식은 정렬 로직을 직접 구현해야 했고, 최솟값을 찾기 위해 추가적인 연산이 필요했습니다. 하지만 PriorityQueue를 사용하면 이러한 복잡한 과정을 생략하고, 훨씬 간결하고 효율적인 코드를 작성할 수 있습니다.
예를 들어, 명예의 전당 문제에서 PriorityQueue를 사용한다면, 다음과 같은 방식으로 코드를 작성할 수 있습니다.
import java.util.PriorityQueue;
public int[] solution(int k, int[] score) {
int[] answer = new int[score.length];
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int i = 0; i < score.length; i++) {
pq.add(score[i]);
if (pq.size() > k) {
pq.poll();
}
answer[i] = pq.peek();
}
return answer;
}
위 코드에서 pq.add(score[i])는 현재 점수를 PriorityQueue에 추가하는 부분입니다. pq.size() > k 조건은 PriorityQueue의 크기가 명예의 전당 목록 크기(k)를 초과하는 경우, 가장 작은 값을 제거하는 역할을 합니다. 마지막으로 answer[i] = pq.peek()는 현재 명예의 전당 목록에서 최하위 점수를 answer 배열에 저장하는 부분입니다.
이처럼 PriorityQueue를 사용하면 정렬과 최소값/최대값 관리에 대한 고민을 덜 수 있어, 더욱 중요한 로직에 집중할 수 있습니다. 물론, PriorityQueue를 사용하기 위해서는 import java.util.PriorityQueue를 통해 해당 클래스를 import해야 합니다.
TODO 프로젝트, 그리고 앞으로의 다짐
이번 스프링 입문 3주차를 통해 TODO 프로젝트를 진행하면서, 웹 개발의 기본 개념을 익히고, 예상치 못한 문제 해결 능력도 키울 수 있었습니다. 특히 PriorityQueue라는 강력한 도구를 알게 된 것은 큰 수확이라고 생각합니다.
물론, 아직 갈 길은 멀고 배울 것도 많습니다. 앞으로도 꾸준히 학습하고, 다양한 프로젝트를 경험하면서 실력을 향상시켜나가도록 하겠습니다. 특히 이번 주에 경험했던 삽질과 깨달음을 잊지 않고, 앞으로는 문제 해결에 더욱 효율적인 접근 방식을 택할 수 있도록 노력할 것입니다. 다음 주에는 또 어떤 새로운 도전을 맞이하게 될까요? 벌써부터 설레는 마음입니다.