유난스런 개발 기록

[JAVA] 프로그래머스 - 최빈값 구하기 본문

알고리즘

[JAVA] 프로그래머스 - 최빈값 구하기

yourhwan 2023. 10. 3. 17:23

 

알고리즘을 공부하면서 자동완성과 막연히 알고 있기에 넘어갔던 문법에 대한 중요성을 깨달았다.

최근 풀었던 문제 중에 가장 어려웠던 문제인 거 같다.배열의 요소와 최빈값 설정을 보자마자 Map을 사용해야겠다는 것은 생각이 났지만, 막상 코드로 구현하려니 어려움이 많았다.

 

해당 문제를 풀기 위해서는 알아두면 좋을 메서드가 있다. (해당 정리는 프로그래머스에서 다른 분이 주석을 달아 둔 것을 인용했습니다.)

getOrDefault : 찾는 키가 존재한다면 찾는 키의 값을 반환하고 없다면 기본 값을 반환하는 메서드
        // getOrDefault(Object key, V DefaultValue)
        // 매개변수 : 이 메서드는 두개의 매개변수를 허용
        // key : 값을 가져와야 하는 요소의 키
        // defaultValue : 지정된 키로 매핑된 값이 없는 경우 반환되어야 하는 기본값
        // 반환값 : 찾는 key가 존재하면 해당 key에 매핑되어 있는 값을 반환하고, 그렇지 않으면 디폴트 값이 반환

Map을 사용했을 경우 키와 밸류를 활용할 수 있는지가 해당 문제의 핵심이라고 할 수 있다.

 

내가 생각한 알고리즘을 글로 정리하자면 

  1. 반복문을 통해 배열 array를 순회하며, 각 요소들의 빈도수를 계산하여 Map에 key와 value로 저장한다.
  2. 반복문을 통해 Map을 순회하며, key와 value를 업데이트 해준다. (key는 배열의 요소, value는 빈도수)
  3. 이후 반복문을 순회하는 동안의 최빈값과 현재까지 찾아 둔 최빈값을 비교하여 최빈값을 업데이트 해준다.
  4. 최빈값이 여러 개일 경우 -1을 리턴한다.

해당 과정을 코드로 구현하기만 하면 된다.

 

 

풀이 코드( 복습을 진행하며 자세한 코드 설명을 추가했습니다.)

import java.util.*;
class Solution {
    public int solution(int[] array) {
        Map<Integer, Integer> frequencyMap = new HashMap<>();
        // 빈도수와 해당 정수를 key와 value로 저장하기 위해 Map 선언
        
        // 빈도수를 저장하기 위해 배열을 순회하는 반복문
        for(int num : array) {
            frequencyMap.put(num, frequencyMap.getOrDefault(num,0)+1);
        }
        // .getOrDefault(Object key, V DefaultValue)
        // key는 값을 가져와야하는 요소의 키
        // DefaultValue는 지정된 키에 매핑 되어진 value가 없으면 반환되어야 하는 기본값
        // 반환값 key값이 존재하면 매핑되어 있는 값을 반환, 그렇지 않으면 기본값을 반환
        
        int mode = -1; // 최빈값의 초기 값을 -1로 선언
        int maxFreq = 0; // 최빈값의 빈도수 초기값을 0으로 선언
        
        // 반복문을 통해 Map을 순회하며 key와 value 조회
        // Map.Entry는 인터페이스로 Map의 내부 인터페이스로 포함되어 있다. Map의 각 항목에 할당되어 있는 key와 value에 접근할 수 있다.
        // Map.Entry<Integer,Integer> entry는 frequencyMap.entrySet()을 통해 가져온 Map의 모든 Key와 Value를 저장해두는 임시 데이터 구조의 역할을 한다고 생각하면 된다.
        for(Map.Entry<Integer,Integer> entry : frequencyMap.entrySet()) {
            int num = entry.getKey();
            int freq = entry.getValue();
            
            if(freq > maxFreq) {
                mode = num; // 최빈값 업데이트
                maxFreq = freq; // 최빈값의 빈도수 업데이트
            }
            else if(freq == maxFreq) {
                mode = -1; // 최빈값이 여러개일 경우 최빈값의 초기값인 -1으로 업데이트 
            }
        }
        
        return mode;
    }
}

 

기본기가 부족하다보니 문제를 보면 어떤 문법을 사용하면 되겠다는 감은 오지만 코드화 시키는 것에는 큰 어려움을 겪어왔다. 

막연한 프로젝트와 개발공부만 해오다가 알고리즘을 처음 시작한 나에겐 나름 까다로운 문제였던 거 같다.

이 문제를 풀면서 막연하게 key와 value에 대한 할당 정도로 알고있던 Map에 대한 기본 개념을 다시 다잡을 수 있어서 오래 기억에 남을 거 같다.