코딩테스트 공부/프로그래머스

[Coding Test : Java] Lv.0 : 최빈값 구하기

규글 2023. 3. 16. 02:01

문제 상황은 다음과 같다.[각주:1]


 최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.


코드

import java.util.*;

class Solution {
    public int solution(int[] array) {
        int answer = 0;
        Map<Integer, Integer> map = new HashMap<>();
        
        for(int tmp : array){
            if(!map.containsKey(tmp)){
                map.put(tmp, 1);
            } else {
                map.replace(tmp, map.get(tmp)+1);
            }
        }
        
        Object[] list = map.values().toArray();
        Object[] keySet = map.keySet().toArray();
        int[] keyList = Arrays.stream(keySet).mapToInt(i -> (int)i).toArray();
        int[] intList = Arrays.stream(list).mapToInt(i -> (int)i).toArray();
        
        int length = intList.length;
        int index = 0;
        for(int j=length-1; j>0; j--){
            for(int i=length-1; i>0; i--){
                int prev = intList[i-1];
                int next = intList[i];
                int prevKey = keyList[i-1];
                int nextKey = keyList[i];

                if(prev > next){
                    intList[i-1] = next;
                    intList[i] = prev;
                    keyList[i-1] = nextKey;
                    keyList[i] = prevKey;
                } else {
                    continue;
                }
            }
        }
        
        if(length !=1 && intList[length-1] == intList[length-2]){
            return -1;
        } else {
            return keyList[length-1];
        }
    }
}

 일단 통과는 했다. 문제는 그것이 아니다. 필자는 HashMap을 활용하고자 했다. 그러나 아직 꼭 결과 전체를 얻어내려고 하는 경향이 있다.

 필자는 HashMap을 활용하여 각 number를 key로, 중복되는 정도를 value로 data를 수집하고자 했다. 여기까지는 좋았는데, 그 다음이 문제다. HashMap의 key Set과 value Set을 얻어 그들을 array로 변경한 뒤, value array를 sort하여 가장 마지막 두 index를 비교하는 방식을 취한 것이다.

 

 다른 사람은 보다 간단한 logic으로 구현했다.[각주:2]

 이 사람은 HashMap만을 활용했으며, Map의 각 key와 value 값을 변수로 logic을 구성했다.

 

import java.util.*;

class Solution {
    public int solution(int[] array) {
        int answer = 0;
        Map<Integer, Integer> map = new HashMap<>();
        
        for(int tmp : array){
            if(!map.containsKey(tmp)){
                map.put(tmp, 1);
            } else {
                map.replace(tmp, map.get(tmp)+1);
            }
        }

        int maxCountKey = -1;
        int maxCountValue = -1;
        int preMaxCountValue = -1;
        
        for(int tmp : map.keySet()){
            if(map.get(tmp) > maxCountValue){
                maxCountValue = map.get(tmp);
                maxCountKey = tmp;
            } else if(map.get(tmp) == maxCountValue){
                preMaxCountValue = map.get(tmp);
            }
        }
        
        if(preMaxCountValue == maxCountValue){
            answer = -1;
        } else {
            answer = maxCountKey;
        }
        
        return answer;
    }
}

 가장 많이 count 된 수, 그 다음으로 많이 count 된 수, 가장 많이 count 된 key 값을 변수로 형성했다. 그리고 HashMap의 각 key Set 전체에 대한 for loop를 구성하여 초기값보다 Map의 value 가 크면 가장 많이 count 된 변수를 update 하도록 했다. 이 과정에서 혹시 같은 값이 나온다고 하면 그것은 두 번째로 많이 count 된 변수를 update 하도록 했다. 그리고 모든 for loop를 통과한 후에 두 값을 비교하여 같으면 -1을, 다르면 가장 많이 count 된 key 값을 return 하도록 했다. 이 과정에서 array에 하나의 숫자만을 가진 경우는 -1과 1로 반드시 다르기 때문에 1이 return 된다.

 

 길이도 훨씬 짧고, 각 test case에 대한 연산 시간도 월등히 짧았던 것을 확인할 수 있었다. 아직도 갈 길이 멀다.

 

Footnote