이번 문제는 프로그래머스 사이트에 공개된 문제입니다.
문제
https://programmers.co.kr/learn/courses/30/lessons/42840
분석/설계
구현을 위해 나눠서 필요한 것들을 생각해봅니다.
1. 수포자는 3명의 찍는 방식을 저장할 배열 필요.
2. 정답 배열과 수포자 패턴 배열을 비교하여 점수를 저장할 배열 필요.
3. 패턴 비교 시 문제가 10000문제 이므로 수포자 1의 경우 1,2,3,4,5로 길이 5의 패턴이므로 5 이상의
길이를 가진 문제일 경우 계속 패턴을 반복하여 비교할 수 있게 인덱스를 적절하게 조정해줘야 함.
3명의 수포자가 각각 패턴이 다르므로 알맞게 조정 필요.
3. 점수가 담긴 배열에서 최댓값을 구해야 함.
4. 최댓값을 2번 과정에서 저장한 점수 배열과 비교하여 누가 최대 득점자인지 구하여 리턴.
구현 코드
public static int[] solution(int[] answers) {
int[] score = {0,0,0}; // 응시자 점수를 담을 배열 생성
ArrayList<Integer> maxScore = new ArrayList<Integer>(); // 최대 점수 담을 ArrayList
int[][] patterns = {{1,2,3,4,5},
{2,1,2,3,2,4,2,5},
{3,3,1,1,2,2,4,4,5,5}}; // 응시자 pattern 배열
for(int i = 0; i < answers.length; i++) {
if (patterns[0][i%5] == answers[i]) { // 1번 응시자
score[0]++;
}
if (patterns[1][i%8] == answers[i]) { // 2번 응시자
score[1]++;
}
if (patterns[2][i%10] == answers[i]) { // 3번 응시자
score[2]++;
}
}
int [] sortScore = score.clone();
Arrays.sort(sortScore);
int max = sortScore[2]; // 정렬해서 max값을 얻음
for(int i = 0; i < score.length; i++) {
if(score[i]==max) {
maxScore.add(i+1); // 인덱스 저장
}
}
int[] answer = new int[maxScore.size()];
for(int i = 0; i < answer.length; i++) {
answer[i] = maxScore.get(i);
}
return answer;
정답 코드(다른 사람의 코드와 비교)
public int[] solution(int[] answer) {
int[] a = {1, 2, 3, 4, 5};
int[] b = {2, 1, 2, 3, 2, 4, 2, 5};
int[] c = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
int[] score = new int[3];
for(int i=0; i<answer.length; i++) {
if(answer[i] == a[i%a.length]) {score[0]++;}
if(answer[i] == b[i%b.length]) {score[1]++;}
if(answer[i] == c[i%c.length]) {score[2]++;}
}
int maxScore = Math.max(score[0], Math.max(score[1], score[2]));
ArrayList<Integer> list = new ArrayList<>();
if(maxScore == score[0]) {list.add(1);}
if(maxScore == score[1]) {list.add(2);}
if(maxScore == score[2]) {list.add(3);}
return list.stream().mapToInt(i->i.intValue()).toArray();
}
비교
1. 정답과 수포자 패턴 비교
정답과 패턴 비교 시 패턴 길이를 하드코딩을 했는데 문제의 수포자가 3명으로 제한되어있지만
N명일 경우 패턴 배열의 length 메서드를 써서 풀어야 합니다.
2. 최대 값 구하기
최대 값을 구하기 위해 Math 클래스의 max를 사용했고 저같은 경우 Arrays 클래스의 sort 메서드를
사용하여 최댓값을 구했습니다.
참고로 Arrays.sort 메서드의 경우 내부 정렬을 위해 기본 자료형은 Quick sort 그리고 객체는 Tim sort
를 사용합니다.
Tim Sort는 참고에 Naver D2 글을 참고하면 도움이 될 것 같습니다.
3. 결괏값 배열 리턴
제 코드에서는 ArrayList의 꺼내어 정답 배열(최대 득점 자) 옮기기 위해 for 문을 사용했는데요.
다른 사람 코드는 stream을 mapToInt 메서드를 활용하여 Int Stream으로 전환 후 toArray 메서드로
배열로 리턴할 수 있게 처리하였습니다.
정리
Stream을 JDK 8부터 소개되었는데 배열, 컬렉션을 다루고 여기서 특정 값을 탐색할 때 아주 유용합니다.
람다를 이용해서 코드량을 많이 줄 일수 있습니다.
익숙한 for 문을 사용한 접근 대신 stream으로 접근도 많이 시도해봐야 해봐야 할 것 같습니다.
stream 관련해서는 잘 정리된 블로그 글이 있어 참고에 링크했습니다.
참고
https://programmers.co.kr/learn/courses/30/lessons/42840
https://d2.naver.com/helloworld/0315536
https://futurecreator.github.io/2018/08/26/java-8-streams/