dayon.log
← 모든 글Algorithm

HashMap으로 추억 점수 합산하기

프로그래머스 추억 점수 문제를 풀며 반복 검색을 HashMap 조회로 바꾸는 방법과 복잡도를 살펴봅니다.

목차
  1. 문제
  2. 이름 목록을 매번 순회하기
  3. HashMap으로 이름과 점수 연결하기
  4. 기억해 둘 HashMap 메서드

문제

프로그래머스 추억 점수 문제에서는 사람 이름 배열 name과 각 사람의 그리움 점수 yearning, 사진마다 등장하는 사람 이름을 담은 photo가 주어집니다. 각 사진 속 사람들의 점수를 더해 사진별 점수 배열을 반환합니다. 명단에 없는 사람은 0점으로 계산합니다.

이름 목록을 매번 순회하기

처음에는 사진 속 이름마다 name 배열을 처음부터 비교할 수 있습니다.

for (int i = 0; i < photo.length; i++) {
    int sum = 0;
    for (String person : photo[i]) {
        for (int n = 0; n < name.length; n++) {
            if (person.equals(name[n])) {
                sum += yearning[n];
                break;
            }
        }
    }
    answer[i] = sum;
}

사진 전체에 등장하는 이름 수를 P, 이름 목록의 길이를 N이라고 하면 최악의 경우 O(P × N)번 비교합니다. 문제 제한에서는 이 방법도 충분히 통과할 수 있지만, 같은 이름 목록을 사진마다 반복 검색합니다.

HashMap으로 이름과 점수 연결하기

이름을 키로, 점수를 값으로 저장하면 사진 속 이름을 조회할 때마다 명단 전체를 훑지 않아도 됩니다.

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] solution(String[] name, int[] yearning, String[][] photo) {
        Map<String, Integer> scoreByName = new HashMap<>();
        for (int i = 0; i < name.length; i++) {
            scoreByName.put(name[i], yearning[i]);
        }

        int[] answer = new int[photo.length];
        for (int i = 0; i < photo.length; i++) {
            for (String person : photo[i]) {
                answer[i] += scoreByName.getOrDefault(person, 0);
            }
        }
        return answer;
    }
}

getOrDefault(person, 0)은 이름이 맵에 없으면 0을 반환합니다. 따라서 별도의 존재 여부 분기 없이 점수를 합산할 수 있습니다.

맵을 준비하는 데 O(N), 사진 속 이름을 한 번씩 처리하는 데 평균 O(P)가 걸려 전체 평균 시간 복잡도는 O(N + P)입니다. 공간 복잡도는 O(N)입니다. HashMap 조회의 O(1)은 평균적인 설명이며, 모든 입력에서 보장되는 절대적인 상수 시간은 아닙니다. 원문에 적힌 ‘최대 100배 빠르다’는 계산량 상한의 비교이지 실제 벤치마크 측정값은 아닙니다.

기억해 둘 HashMap 메서드

Map<String, Integer> scores = new HashMap<>();

scores.put("may", 5);                         // 추가 또는 갱신
int score = scores.getOrDefault("jane", 0); // 기본값을 포함해 조회
boolean exists = scores.containsKey("may"); // 키 존재 여부
scores.put("may", scores.getOrDefault("may", 0) + 1); // 빈도 누적 패턴

문자열 값 비교에는 == 대신 equals를 사용합니다. 키와 값이 1:1로 연결되거나, 키별 개수와 합계를 반복해서 조회하는 문제라면 HashMap이 유용합니다.