[Java] 자바 알고리즘, 모의고사 level1

반응형
모의고사
문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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입니다.

입출력 예 #2

  • 모든 사람이 2문제씩을 맞췄습니다.

 

나의 풀이

import java.util.ArrayList;
class Solution {
    public int[] solution(int[] answers) {
        int[] answer = {};
        int[] person1 = {1,2,3,4,5}; //이만큼씩 반복
        int[] person2 = {2,1,2,3,2,4,2,5};
        int[] person3 = {3,3,1,1,2,2,4,4,5,5};
        int answer1=0, answer2 =0, answer3 =0;
        
        for(int i =0; i<answers.length; i++){
            if(person1[i%person1.length] == answers[i]) answer1++;
            if(person2[i%person2.length] == answers[i]) answer2++;
            if(person3[i%person3.length] == answers[i]) answer3++;
        }
        int max = Math.max(Math.max(answer1, answer2),answer3); // max값 구하기
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(max==answer1) list.add(1); //max값이랑 같으면 넣는다.
        if(max==answer2) list.add(2);
        if(max==answer3) list.add(3);
        
        answer = new int[list.size()];
        
        for(int i =0; i<answer.length; i++) {
        	answer[i] = list.get(i);
        }
        
        return answer;
    }
}

- 하드코딩이 많습니다. 일단 이 풀이법은 사람이 3명이라고 못박아놨기때문에 가능한 풀이법인것 같습니다. 2차원배열로 사람의 수까지 랜덤하게 될 경우 제한적일것 같네요.

- person 배열은 패턴을 담은 배열입니다. 이 배열은 첫번째 포문에서 답을 맞추는데에 사용됩니다.

- 각 사람의 정답수를 ++ 해주면 Math.max 메소드를 이용하여 세사람의 정답개수중 가장 많이 맞춘사람의 갯수를 구합니다. 그래야 max 값이 같은 경우 == 비교해주면 max값을 정답수로 갖는 사람을 골라낼 수 있습니다.

- 그렇게 구한 answer(사람 인덱스)를 반환해줍니다.

 

 

다른사람의 풀이
class Solution {
    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();
    }
}

- 차이는 아마 return 문에서 저는 순수배열을 리턴했고, 이분은 list를 stream으로 중간처리를 통해서 배열로 리턴했습니다. 제 노트북으로 제 소스와 이분소스를 돌려봤는데 대략 4배정도 제 소스가 빨랐습니다. 이유는 스트림으로 내부반복자를 사용해서 개발자가 변환과정에만 집중하였지만 그부분에서 좀더 많은 로직이 들어있지 않나 싶습니다.

- 아무래도 직접 반복자 돌려서 변환하는게 더 빠른것 같습니다. 맨아래 코드 3줄이냐 1줄이냐의 차이였는데 이부분은 코딩테스트할 때 성능부분을 고려하려면 중요할 것 같습니다

반응형

댓글

Designed by JB FACTORY