카테고리 없음

[JAVA] 음수를 포함한 영역의 최빈값을 계산하기

이민재 2022. 10. 9. 23:11

※ 본 포스팅은 프로그래머스에 있는 연습문제 풀었던 내역을 아카이빙하기 위해 작성했습니다.

작성자의 공부를 목적으로 작성된 포스팅입니다.

이 포스팅은 방법을 제시한다기보다 제가 어떤 어려움을 겪었는지를 기록하는 목적으로 작성되었습니다.

혹시나 더 좋은 솔루션이 있으실 경우 태클도 환영입니다!! 

 

 

주어진 array 라는 배열이 있고

그 배열의 길이는 0과 100 사이이며

array의 원소는 절대값 1000 이하일 때 

음수가 최빈값으로 올 경우에 대비해서 처음에는 

각 숫자를 카운팅하기 위해 배열을 선언할 때 단순하게 1000을 더했었다.

int max = 0;
int answer = 0;
int [] count = new int[array.length+1001];

이런 식으로

0을 처리하기 위해서

또 6번째 배열은 index[5]로 표시해야하기 때문에 1을 더해주고 음수 영역이라고 생각했던 1000을 더해서 array.length+1001이라고 코드를 짰었다.

작은 숫자일 때는 문제가 없었으나... 문제는

int[] array = {1, -3, -3, -3, -4, -4, -4,5,5,5,6,7,8,9,10,
999,999,999,999,-999,-999,-999,-999,-999};

이런 상황일 때 나타났다.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1999 out of bounds for length 1025

이 에러문구를 보고 나서 무릎을 탁 쳐버렸다.

처음엔 안일하게 음수를 넣기 위해서 음수가 나올 수 있는 영역인 1000만 더했는데,

이렇게 해버리면 array.length+1001는 끽해봐야 1000에서 크게 벗어나지 못하는 수준이라 받아들일 수 있는 수의 범위가 한정되어 있다.

결국 -1000 < array의 원소 < 1000을 표현하려면

카운트를 할 변수를 2001개만큼 인덱스를 선언해줘야했다.(양수 1000, 음수1000, 0을 처리할 1자리)

그래서 이렇게 코드를 짜보니 에러 없이 잘 실행이 되었다.

 

public static void main(String[] args) {
    // 최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 
    // 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 
    // 최빈값이 여러 개면 -1을 return 합니다.
    int[] array = {1, -3, -3, -3, -4, -4, -4,5,5,5,6,7,8,9,10,
    999,999,999,999,-999,-999,-999,-999,-999};
    // 최빈값을 받을 변수 선언 및 초기화
    int answer = 0;		
    int [] count = new int[2001];

    answer = mode(array, count);		

    System.out.println(answer);
}

private static int mode(int[] array, int[] count) {
    int max = 0;		
    int answer = 0;
    for(int i = 0;i<array.length;i++) { // array.length의 길이만큼 돌아갈 for문
        // 배열에 들어가 있는 값이 양수일 경우 처리할 구문
        if(array[i]>0){  
            count[array[i]]++;
        }
        // 배열에 들어가 있는 값이 음수일 경우 처리할 구문
        else if(array[i]<0){ 
            count[(array[i]*(-1))+1000]++;
        }else{
            array[0]++;		// 배열의들어가 있는 값이 0일 경우 처리할 구문
        } 
    }
    for( int i=0; i<count.length; i++) {
		 // array배열과 count 배열을 한번에 합쳐서 생각했더니
         // 코드가 너무 꼬여서 for문을 두번 사용하였다.
         // 애초에 윗 단계에서 count에 값을 다 쌓은 후에 써야했다.
                               
        // for문을 돌면서 count 각 항에 쌓인 값이 가장 높은 항을 찾는다.
        if(count[i] > max) {	
            max = count[i];	// 최대값은 따로 저장을 해두고
            answer = i;	// 그 최대값이 있던 항의 인덱스 번호가 원래 array에 있던 숫자다.
        }
        for(int j=i+1; j<count.length; j++) {// 최빈값이 2개라면 -1을 리턴하는 구문
            if(count[i]==max && count[j]==max) {
                answer = -1;
            }
        }
    }
    // 위에서 음수일 때 인덱스번호를 1000을 더했기 때문에 데이터원복
    if(answer > 1000){	
        answer = (answer - 1000)*(-1);
    }
    return answer;
}