이렇게 노가다스럽게 하는게 맞는건지 모르겠지만 어쨌든 통과됐다...
import java.util.*;
class Solution {
public int[] solution(int[] answers) {
int[] answer = {};
List<Integer> answerList = new ArrayList<>();
// 수포자들의 찍는 방식 2차원 배열
int[] type1 = {1, 2, 3, 4, 5};
int[] type2 = {2, 1, 2, 3, 2, 4, 2, 5};
int[] type3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
int[][] types = {type1, type2, type3};
int maxCnt = 0; // 맞은 문제 수 최대값
int correctCnt = 0; // 맞은 문제 수
for (int i = 0; i < types.length; i++) {
for (int j = 0; j < answers.length; j++) {
// 수포자 한 명씩 돌면서 맞은 문제 수 카운트
if (types[i][j%types[i].length] == answers[j]) correctCnt++;
}
if (correctCnt >= maxCnt) {
int answerVal = i + 1;
if (correctCnt > maxCnt) {
// 지금까지 중 제일 많은 문제를 맞힌 경우, 이전의 값들 List에서 제거
answerList.removeIf(n -> (n < answerVal));
}
// 지금까지 제일 많이 맞췄거나, 동점일 경우 List에 추가 및 맞은 문제 수 최대값 갱신
answerList.add(answerVal);
maxCnt = correctCnt;
}
correctCnt = 0;
}
answer = answerList.stream().mapToInt(i->i).toArray();
return answer;
}
}
answerList.removeIf()
는 람다 표현식으로 조건을 작성해, 해당하는 요소들을 모두 삭제할 수 있도록 해준다.
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
list.removeIf(n -> (n % 3 == 0));
// 결과 : [1, 2, 3, 4, 5, 6, 7, 8, 9] > [1, 2, 4, 5, 7, 8]
answer = answerList.stream().mapToInt(i->i).toArray()
로 List를 Array 형태로 변환.
다른 사람 풀이 참고해서 조금 더 개선해보았다...
import java.util.*;
class Solution {
public int[] solution(int[] answers) {
// 수포자들의 찍는 패턴 2차원 배열에 담기
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}
};
// 맞은 개수를 배열에 담기
int[] correct = new int[3];
for (int i = 0; i < patterns.length; i++) {
for (int j = 0; j < answers.length; j++) {
if(patterns[i][j%patterns[i].length] == answers[j]) correct[i]++;
}
}
// 맞은 개수 max 값 구하기
int max = Math.max(correct[0], Math.max(correct[1], correct[2]));
// List에 가장 많이 맞힌 사람들 add
List<Integer> answerList = new ArrayList<>();
for (int i = 0; i < correct.length; i++) {
if(max == correct[i]) answerList.add(i + 1);
}
// List를 Array로 변환
int[] answer = new int[answerList.size()];
int cnt = 0;
for (int num : answerList)
answer[cnt++] = num;
return answer;
}
}
for 문을 돌면서 max 값을 갱신하는 방법보다, max 값을 구하고 비교하여 index 값으로 add 하는 방법이 나은 것 같다...
추가로, stream을 쓰면 가독성이 좋고 편리하다는 장점이 있긴 하지만 속도 부분에서 차이가 꽤 나는 것 같다.
테스트 1 〉 통과 (2.05ms, 75MB)
테스트 2 〉 통과 (1.88ms, 76.3MB)
테스트 3 〉 통과 (1.89ms, 71.9MB)
List를 Array로 변환하는 과정에 answerList.stream().mapToInt(i->i).toArray();
대신, for문을 이용해 직접 대입했다.
max 값을 구할 때도 Arrays.stream(correct).max().getAsInt();
대신, Math.max(correct[0], Math.max(correct[1], correct[2]));
를 사용했다.
그랬더니 이렇게나 속도가 줄었다.
테스트 1 〉 통과 (0.04ms, 75MB)
테스트 2 〉 통과 (0.04ms, 75.4MB)
테스트 3 〉 통과 (0.04ms, 73.6MB)