JAVA/코드 과제

[JAVA] 최빈값 구하기

나는나는용 2023. 2. 20. 18:11
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/120812

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1차- 그냥 처참히 실패

package programmers.최빈값찾기;

public class Solution {
	public static void main(String[] args) {
		int[] array = {1,1,2,2};
		Solution sol = new Solution();
		System.out.println(sol.solution(array));
	}

    	public int solution(int[] array) {
            int answer = 0;
            int max=0; //가장 큰 원소 값
            int exist=0;
            
            //배열에서 가장 큰 원소 찾기
            for(int i=1;i<array.length-1;i++) {
            	if(array[max]<array[i]) {
            		max=i;
            	}
            }
            max=array[max];
            
            //가장 큰 원소값의 크기+1만큼 counter 배열 생성
            //그래야 counter배열의 마지막 인덱스값이 가장 큰 원소값과 같다.
            int[] counter= new int[max+1];
           
            
            for(int i=0;i<array.length-1;i++) {
            	int a=array[i];
            	counter[a]++;
            }
            
            int[] multip = new int[max+1];
            for(int i=0;i<counter.length-1;i++) {
            	int a=counter[i];
            	if(a!=0) {
            		multip[a]++;
            	}
            }
            
            for(int i=0;i<multip.length-1;i++) {
            	if(multip[i]!=0) {
            		exist=i;
            	}
            }
            
            if(multip[exist]>1) {	//최빈값이 중복되는 경우
            	answer=-1;
            }else if(multip[exist]==1) {	//최빈값이 유일한 경우
            	for(int i=0;i<counter.length-1;i++) {
            		if(counter[i]==exist) {
            			answer=i;
            		}
            	}
            }
                        
            //배열의 원소가 한개일 경우.
            if(array.length==1) {
            	answer = array[0];
            }
            
            return answer;
        }
}

위 코드에서 문제점은?

일단 돌아가지 않는다. 왜 안돌아갈까?

 💡 막힌다면 다시 처음부터 돌아가서 필요한 애들은 꼭 써주었는지와 불필요한 애들까지 써버렸지는 않은지 확인해보자.

 

굳이 multip이라는 배열을 생성해서,
exist변수까지 생성해서,
multip배열의 인덱스에 값의 존재 유무를 확인할 필요는 없다.

 

그러므로

  1. 불필요한 multip과 exist 삭제.
  2. 빈도수를 나타내는 counterMax의 최대 값이 정해졌다면, 이보다 더 큰 값이 있는지, 아니면 중복되는 값이 있는지만 확인.
  3. 답 도출
    • count변수를 통해 counterMax와 같은 값을 갖는지 확인하고, 확인한 결과,중복되는 값이 있다면 -1이 답
    • 더 큰 값이 없고, counterMax가 유일한 큰 값이라면 counterMax의 빈도를 갖는 원소가 답
    • 더 큰 값이 있다면, counterMax최빈값의 원소가 답.
  • 그리고, 메서드 이름들도 예쁘게 바꿔보고, 동일 역할을 하는 메서드를 따로 써줄 필요 없이 통일시켜 호출하기만 해보자.

2차- 일단은 돌아가는 코드

package programmers.최빈값찾기.sol;

public class Solution {
	public static void main(String[] args) {
		int[] array = { 1, 1, 2 };
		Solution sol = new Solution();
		System.out.println(sol.solution(array));
	}

	public int solution(int[] array) {
		int answer = 0;
		int count = 0;
		int arrayMax = 0;
		int counterMax = 0;
		int result = 0;
		
		// 배열의 원소가 한개일 경우.
		if (array.length == 1) {
			answer = array[0];
		}
		
		// 배열에서 가장 큰 원소 찾기
		arrayMax = findMaxByArray(array);

		// 가장 큰 원소값의 크기+1만큼 counter 배열 생성
		// 그래야 counter배열의 마지막 인덱스값이 가장 큰 원소값과 같다.
		int[] counter = new int[arrayMax + 1];

		for (int i = 0; i < array.length; i++) {
			counter[array[i]]++;
		}

		counterMax = findMaxByArray(counter);
		for (int i = 0; i < counter.length; i++) {
			if (counter[i] == counterMax)
				count++;
		}

		for (int i = 0; i < counter.length; i++) {
			if (counter[i] == counterMax)
				result = i;
		}

		if (count > 1)
			answer = -1;
		else
			answer = result;

		return answer;
	}

	public int findMaxByArray(int[] arr) {
		int max = 0;
		for (int i = 0; i < arr.length; i++) {
			if (max < arr[i])
				max = arr[i];
		}

		return max;
	}
}

3차-찐 최 종

package programmers.최빈값찾기.sol;

public class Solution2 {
	public static void main(String[] args) {
		int[] array = { 1, 1, 2 };
		Solution2 sol = new Solution2();
		System.out.println(sol.solution(array));
	}

	public int solution(int[] array) {
		int answer = 0;
		int count = 0;
		int arrayMax = 0;
		int counterMax = 0;

		// 배열의 원소가 한개일 경우.
		if (array.length == 1) {
			answer = array[0];
		}

		// 배열에서 가장 큰 원소 찾기
		arrayMax = findMaxByArray(array);

		// 가장 큰 원소값의 크기+1만큼 counter 배열 생성
		// 그래야 counter배열의 마지막 인덱스값이 가장 큰 원소값과 같다.
		int[] counter = new int[arrayMax + 1];

		//'array배열의 원소'를 인덱스번호로 갖는 counter배열의 원소는
		//array배열의 원소의 빈도수.
		for (int i = 0; i < array.length; i++) {
			counter[array[i]]++;
		}

		// counter배열에서 가장 큰 원소 찾기(최빈값은 몇 회인지 찾기)
		counterMax = findMaxByArray(counter);

		// counter배열을 돌면서 counterMax와 같은 값이 있는지 확인.
		// 즉, 똑같은 최빈값이 존재하는지 확인
		for (int i = 0; i < counter.length; i++) {
			if (counter[i] == counterMax) // 같은 최빈값 빈도수(횟수)가 있다면
				count++; // count변수 증가.
		}

		// counter배열에서 counterMax의 값을 원소로 갖는 인덱스가 최빈값.
		// 왜냐하면, counter배열의 인덱스번호 == array배열에서의 원소
		for (int i = 0; i < counter.length; i++) {
			if (counter[i] == counterMax)
				answer = i;
		}

		//counterMax만 유일한 최빈값 회수가 아니라면 count는 1 초과일 것.
		if (count > 1)
			answer = -1;	//때문에 -1.

		return answer;
	}

	public int findMaxByArray(int[] arr) {
		int max = 0;
		for (int i = 0; i < arr.length; i++) {
			if (max < arr[i])
				max = arr[i];
		}

		return max;
	}
}

result를 굳이 쓸 필요없이 바로 answer로 넘겨줘도 되기 때문에 result변수를 삭제해주었다.

막 크게 바뀐것은 없다..

그래도 뭐라도 좀 바꿔보자 하고 주석을 좀 더 추가했을 뿐^^

728x90