본문 바로가기
🍪 Ect/#Study

[99클럽 코테 스터디] 15일차 TIL 완전탐색

by 개발한 너굴씨 2024. 8. 5.
728x90

 

 

오늘의 문제는 프로그래머스

 

모의고사

 

 

문제

 

 

 

문제 설명 

 

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]를 순서대로 반복해 찍습니다. 

정답이 담긴 answers 배열이 주어졌을 때, 문제를 많이 맞힌 사람이 누구인지 배열에 담아 반환하면 되는 문제입니다. 

대신, 가장 높은 점수를 받은 사람이 여러명일 경우, 값을 오름차순으로 정렬해 반환해야 합니다. 

예를 들어 정답이 [1, 2, 3, 4, 5]이면 반환값은 [1]이고 정답이 [1, 3, 2, 4, 2]이면, 반환값은 [1, 2, 3]입니다. 

 

 

 

문제 풀이 시간 

권장 풀이 시간은 30분이었고, 저는 40분이 걸렸습니다. 

 

 

 

문제 접근 방식

반복문을 통해 answers의 길이에 맞게 각 수포자의 답안을 배열에 담습니다. 이 때 각 수포자 별 정답을 찍는 규칙을 미리 배열에 담아 놓고 % 연산을 사용합니다. 

각 자의 답안을 배열에 저장했으면 정답과 답안을 비교하여 점수를 셉니다. 만약 점수가 최대값일 경우 리스트에 추가한 뒤 배열로 변환하여 반환합니다. 

 

 

 

문제 풀이

import java.util.ArrayList;

class Solution {
    public int[] solution(int[] answers) {
        
        int len = answers.length;
    
        int[] answer1 = new int[len];
        int[] answer2 = new int[len];
        int[] answer3 = new int[len];
        
        int[] num1 = {1, 2, 3, 4, 5};
        int[] num2 = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] num3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
        
        for (int i = 0; i < len; i++) {
            answer1[i] = num1[i % num1.length];
            answer2[i] = num2[i % num2.length];
            answer3[i] = num3[i % num3.length];
        }
        
        int score1 = 0;
        int score2 = 0;
        int score3 = 0;

        for (int i = 0; i < len; i++) {
            if (answer1[i] == answers[i]) {
                score1++;
            }
            if (answer2[i] == answers[i]) {
                score2++;
            }
            if (answer3[i] == answers[i]) {
                score3++;
            }
        }
        
        int max = Math.max(score1, Math.max(score2, score3));
        
        ArrayList<Integer> answerList = new ArrayList<>();
        
        if (score1 == max) {
            answerList.add(1);
        }
        if (score2 == max) {
            answerList.add(2);
        }
        if (score3 == max) {
            answerList.add(3);
        }
        
        int[] answer = new int[answerList.size()];
        for (int i = 0; i < answerList.size(); i++) {
            answer[i] = answerList.get(i);
        }
        
        return answer; 
    }
}

 

 

나머지 연산을 통해 답안 배열 저장하기 

주어진 찍는 규칙을 반복해 정답 배열의 길이에 맞게 답안을 배열에 저장합니다. 나머지 연산을 사용한 이유는 배열의 인덱스를 반복적으로 순환할 수 있기 때문입니다. 예를 들어 i % num1.length는 아무리 i가 커져도 num1 배열의 길이를 넘지 않으면서 반복적으로 주어진 찍는 규칙의 값을 저장합니다. 

 

 

 

Math.max를 활용해 3개의 정수 비교하기

원래 Math.max는 두 개의 인자를 받는 메서드지만 이를 변형하면 위와 같이 3개의 정수를 비교할 수 있습니다. 

int max = Math.max(score1, Math.max(score2, score3));

 

 

 

리스트를 통한 동적 저장 및 배열 반환하기 

리스트를 사용해 점수가 가장 높은 사람의 번호를 동적으로 저장합니다. 그리고 이를 배열로 변환해 반환합니다. 

가장 높은 점수를 받은 사람이 여러 명일 경우, 리스트의 번호를 오름차순으로 저장해서 반환합니다. 그 이유는 answerList에 추가하는 순서가 번호 순이기 때문에 오름차순으로 저장되는 것입니다. 예를 들어 score1, score2, score3이 모두 최대 점수와 같다면 answerList에 [1, 2, 3]이 순서대로 저장되게 됩니다. 

  • score1이 최대 점수와 같으면 1을 추가합니다.
  • score2가 최대 점수와 같으면 2를 추가합니다. 
  • score3이 최대 점수와 같으면 3을 추가합니다. 

 

 

 

 

개선할 부분 

현재 코드에선 수포자의 답안을 배열에 저장한 다음 정답과 비교하는 방식으로 작성돼 있습니다. 하지만 수포자의 답안을 미리 배열에 저장하는 대신 바로 점수를 계산하는 방법을 사용하면 불필요한 부분을 생략할 수 있습니다. 

 

 

 

 

 

 

이렇게 오늘 15일차 TIL을 작성해 보았습니다.

 

 

 

 

728x90

댓글