[프로그래머스 코딩테스트] 완전탐색 - 모의고사

EUN JY·2022년 3월 4일
1

Coding Test

목록 보기
6/9

이렇게 노가다스럽게 하는게 맞는건지 모르겠지만 어쨌든 통과됐다...

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)
profile
개린이

0개의 댓글