Binary Journey

[코딩테스트합격자되기-자바편] 문제04. 모의고사 본문

Algorithm/코딩테스트합격자되기-자바편

[코딩테스트합격자되기-자바편] 문제04. 모의고사

binaryJournalist 2024. 12. 26. 19:09
반응형
💡 해당 풀이는 코딩 테스트 합격자되기 - 자바편 에서 발췌된 내용을 바탕으로 작성되었습니다.

 

문제

출처: 프로그래머스 - 모의고사

 

내용

 

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.

1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution() 함수를 작성해주세요.

 

제한 조건

  • 시험은 최대 10,000 문제로 구성되어있습니다.
  • 문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
  • 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.

 

입출력의 예

answers return
[1, 2, 3, 4, 5] [1]
[1, 3, 2, 4, 2] [1, 2, 3]

 

기록하기

💡 어디까지 생각해봤는지 단계적으로 기록해봅니다.

 

  1. 1, 2, 3번 수포자 찍는 방식 규칙을 파악한다.
    • 1번 수포자: 1, 2, 3, 4, 5 반복
    • 2번 수포자: 2, 1, 2, 3, 2, 4, 2, 5 반복
    • 3번 수포자: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 반복
  2. 1, 2, 3번 수포자 모두 수학 점수 0점부터 시작한다.
  3. 작성한 답이 답안과 일치하면 점수를 +1 더한다.

 

풀이

풀이 시간

시작 시각 종료 시각 총 소요 시간
18:17 18:52 35분

 

 

문제 분석

 

제약 사항 파악 & 테스트 케이스 작성

  • 시험은 최대 10,000 문제
  • 문제의 정답은 1, 2, 3, 4, 5중 하나
  • 가장 높은 점수를 받은 사람이 여럿일 경우 오름차순 정렬

 

입력값 분석

💡 입력값을 분석하면 문제에서 요구하는 알고리즘의 시간 복잡도를 간접적으로 파악할 수 있습니다.

 

 

의사 코드 작성

💡 의사 코드는 동작 중심으로 작성하는 것이 중요합니다.

💡 의사 코드는 문제 해결 순서로 작성합니다.

💡 의사 코드를 충분히 테스트해봅니다.


int[] solution(int[] answers) {
    1번_수포자 = {1, 2, 3, 4, 5};
    2번_수포자 = {2, 1, 2, 3, 2, 4, 2, 5};
    3번_수포자 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};

    점수 = new int[3];
    for (i = 0; answers 길이까지) {
        // 1. 1번 수포자 확인 후 정답일 시  + 1
        if (answer[i] == 1번_수포자[i%1번_수포자.length]) {
            점수[0]++;
        }
        // 2. 2번 수포자 확인 후 정답일 시  + 1
        if (answer[i] == 2번_수포자[i%2번_수포자.length]) {
            점수[1]++;
        }
        // 3. 3번 수포자 확인 후 정답일 시  + 1
        if (answer[i] == 3번_수포자[i%3번_수포자.length]) {
            점수[2]++;
        }
    }
    최고점수 = max(점수)
    return 최고점수와_일치하는_점수의_인덱스에_+1_한_값들의_정수형배열
}

 

 

구현

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

class Solution {
    public int[] solution(int[] answers) {
        int[] candidate1 = {1, 2, 3, 4, 5};
        int[] candidate2 = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] candidate3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};

        int[] scores = new int[3];

        for (int i = 0; i < answers.length; i++) {
            // 1. 1번 수포자 확인 후 정답일 시  + 1
            if (answers[i] == candidate1[i%candidate1.length]) {
                scores[0]++;
            }
            // 2. 2번 수포자 확인 후 정답일 시  + 1
            if (answers[i] == candidate2[i%candidate2.length]) {
                scores[1]++;
            }
            // 3. 3번 수포자 확인 후 정답일 시  + 1
            if (answers[i] == candidate3[i%candidate3.length]) {
                scores[2]++;
            }
        }

        int maxScore = IntStream.of(scores).max().getAsInt();
        List<Integer> tmps = new ArrayList<>();

        for (int i = 0; i < scores.length; i++) {
            if (scores[i] == maxScore) {
                tmps.add(i + 1);
            }
        }

        int[] result = new int[tmps.size()];
        for (int i = 0; i < tmps.size(); i++) {
            result[i] = tmps.get(i);
        }

        return result;
    }
}

 

 

복기하기

저자 권장 시간 권장 시간 복잡도
30분 O(N)

 

 

답안과 나의 풀이를 비교해보세요

import java.util.ArrayList;  
import java.util.Arrays;

class Solution {
    public static int[] solution(int[] answers) {
        // 수포자들의 패턴  
        int[][] pattern = {  
            {1, 2, 3, 4, 5},  
            {2, 1, 2, 3, 2, 4, 2, 5},  
            {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}  
        };  

        // 수포자들의 점수를 저장할 배열  
        int[] scores = new int[3];  

        // 각 수포자의 패턴과 정답이 얼마나 일치하는지 확인  
        for (int i = 0; i < answers.length; i++) {  
            for (int j = 0; j < pattern.length; j++) {  
                if (answers[i] == pattern[j][i % pattern[j].length]) {  
                    scores[j]++;  
                }  
            }  
        }  

        // 가장 높은 점수 저장  
        int maxScore = Arrays.stream(scores).max().getAsInt();  

        // 가장 높은 점수를 가진 수포자들의ㅣ 번호를 찾아서 리스트에 담음  
        ArrayList<Integer> answer = new ArrayList<>();  

        // 가장 높은 점수를 가진 수포자들의 번호를 찾아서 리스트에 담음  
        for (int i = 0; i < scores.length; i++) {  
            if (scores[i] == maxScore) {  
                answer.add(i + 1);  
            }  
        }  

        return answer.stream().mapToInt(Integer::intValue).toArray();
    }
}
  • 2차원 배열로 패턴을 통합 관리 -> 더 깔끔하고 확장성이 좋음
  • 이중 for문으로 처리 -> 코드는 더 간결하지만, 실행 시간은 약간 더 걸릴 수 있음
  • stream을 사용해 변환 -> 더 현대적이고 간결한 방식
  • 주석을 통한 코드 설명이 더 명확함
반응형