[프로그래머스] Lv.1 모의고사 (Java)

subbni·2023년 1월 27일
0

프로그래머스

목록 보기
8/23

문제

나의 풀이

코드

import java.util.ArrayList;
class Solution {
    public int[] solution(int[] answers) {
        String answer1 = new String(new char[answers.length/5+1]).replace("\0","12345")
            .substring(0,answers.length);
        String answer2 = new String(new char[answers.length/8+1]).replace("\0","21232425")
            .substring(0,answers.length);
        String answer3 = new String(new char[answers.length/10+1]).replace("\0","3311224455")
            .substring(0,answers.length);
        
        int[] cnt = new int[3];

        for(int i=0;i<answers.length;i++) {           
            if(answer1.charAt(i)-'0'==answers[i]) cnt[0]++;
            if(answer2.charAt(i)-'0'==answers[i]) cnt[1]++;
            if(answer3.charAt(i)-'0'==answers[i]) cnt[2]++;     
        }
        
        int max = Math.max(cnt[0],Math.max(cnt[1],cnt[2]));
        int maxCnt = 0;      
        for(int i=0;i<3;i++) {
            if(max == cnt[i]) {
                cnt[i]=-1;
                maxCnt++;
            }
        }
        
        int[] answer = new int[maxCnt];
        int idx = 0;
        for(int i=0;i<3;i++) {
            if(cnt[i]<0) answer[idx++] = i+1;
        }
        
        return answer;
    }
}
  • String answer1,String answer2,String answer3 : 각 수포자들이 찍은 정답들.
    수포자 1은 12345의 5문자가 반복되고, 수포자2는 21232425의 8문자가, 수포자3은 3311224455의 10문자가 반복된다.
    new String(new char[answers.length/(반복되는 문자의 수)+1])를 통해 최소한으로 필요한 배열의 크기를 설정하고, replace("\0",반복되는 문자열) 으로 각 배열 원소 하나에 반복되는 문자열을 대치시켜주었다.

    이 때 "\0"은 char 배열을 생성하면 각 원소에 들어가는 기본형으로, "\u000"으로 바꿔도 정상 동작한다.

이후 .substring(0,answers.length)를 실행하여 실제 문제 길이만큼 잘라주었는데, 지금 생각해보니 어짜피 실제 정답과 비교할 때 for문을 answers.length만큼만 도므로 이 작업은 불필요한 것 같다.

  • int[] cnt : 수포자 1,2,3이 찍은 정답 중 맞은 것의 개수.
    cnt[i] 는 수포자 i-1의 정답 중 맞은 것의 개수를 의미한다.

이후 for문을 돌면서 각각 맞은 것이 있으면 카운트를 올려준다.

  • int max : 가장 많이 맞춘 정답의 수
  • int maxCnt : '가장 많이 맞춘 정답'을 가진 수포자 수

원래는 리스트와 스트림, 람다식을 이용해서 풀었다.

        int max = Math.max(cnt[0],Math.max(cnt[1],cnt[2]));
        ArrayList<Integer> list = new ArrayList<>();

        for(int i=0;i<3;i++) {
            if(max == cnt[i]) {
                list.add(i+1);
            }
        }

        return list.stream().mapToInt(i->i).toArray();

원래 이렇게 제출하고 통과하였는데, 시간이 오래걸려 단순 for문으로 바꾸었다.
바꾼 코드가 더 길기는 하지만, 성능은 훨씬 좋다 🙂

다른 풀이

class Solution {
    public int[] solution(int[] answers) {
        int[] arr = new int[3];
        int[] a = {5,1,2,3,4};
        int[] b = {5,2,1,2,3,2,4,2};
        int[] c = {5,3,3,1,1,2,2,4,4,5};

        for(int i = 0; i < answers.length; i++){
            if(answers[i] == a[(i+1)%5]) arr[0]++;
            if(answers[i] == b[(i+1)%8]) arr[1]++;
            if(answers[i] == c[(i+1)%10]) arr[2]++;
        }

        int max = arr[0];

        if(max < arr[1]) max = arr[1];
        if(max < arr[2]) max = arr[2];

        if(max == arr[0] && max == arr[1] && max == arr[2]) return new int[]{1,2,3};
        else if(max == arr[0] && max == arr[1]) return new int[]{1,2};
        else if(max == arr[0] && max == arr[2]) return new int[]{1,3};
        else if(max == arr[1] && max == arr[2]) return new int[]{2,3};
        else if(max == arr[0]) return new int[]{1};
        else if(max == arr[1]) return new int[]{2};

        return new int[]{3};
    }
}

나는 각 answer들을 String에 넣어 관리하였는데 위 풀이는 배열에 직접 넣어 나머지 연산으로 맞은 횟수를 카운트하였다.
사실 나는 이 문제 전에 풀었던 문제에서 String을 계속 사용해왔어서 무의식적으로 String을 이용해서 푼 것 같은데, 사실 이 풀이처럼 배열을 이용하는 게 정석인 것 같다.
한 가지 궁금한 것은 . . .

        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};

        for(int i = 0; i < answers.length; i++){
            if(answers[i] == a[(i)%5]) arr[0]++;
            if(answers[i] == b[(i)%8]) arr[1]++;
            if(answers[i] == c[(i)%10]) arr[2]++;
        }

제일 기본인 위 코드처럼 풀지 않고 풀이처럼 푼 이유가 따로 있는지 궁금하다.

profile
개발콩나물

0개의 댓글