[JAVA/프로그래머스] 완전탐색_모의고사

👀 문제

https://programmers.co.kr/learn/courses/30/lessons/42840

👊 첫 번째 도전

1. 설계

  1. 이차원 배열을 생성하여 3명의 정답 패턴을 저장한다.
  2. 이중 for문으로 학생 수 만큼, 패턴이 가장 큰 학생(3번 학생)기준으로 돌린다.
  3. 맞은 문제 갯수를 세어 cntArray에 저장한다.
  4. 3명의 정답수를 모두 계산했으면, 가장 많이 맞힌 학생을 찾아 max에 저장한다.
  5. 공동 1등이 있는지 for문으로 판별한다.
  6. 공동이 있을 경우 오름차순으로 정렬하여 리턴한다.

2. 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.util.Arrays;
import java.util.Collections;
/**
 *
 * @author HEESOO
 *
 */
 class Solution {
     public int[] solution(int[] answers) {
         int[] answer = {};
         int[][] person={{1,2,3,4,5},
                         {2,1,2,3,2,4,2,5},
                         {3,3,1,1,2,2,4,4,5,5}
                       };//제일 긴 3번이 10개임
         int[] cntArray=new int[3];
         int q=0;
         int cnt=0;
         for(int i=0;i<3;i++){
             for(int j=0;j<10;j++){
                 if(person[i][j]==0){//1,2번은 5,8개가 끝나면 다시 처음부터 반복
                     j=-1;
                     continue;
                 }
                 if(person[i][j]==answers[q]){//맞았으면
                     cnt++;
                 }
                 if(q==answers.length-1){//마지막 문제이면
                     cntArray[i]=cnt;
                     cnt=0;
                     q=0;
                     break;
                 }
                 q++;
             }
         }
         int max=0;
         for(int i=1;i<cntArray.length;i++){
             if(cntArray[i]>cntArray[max]){
                 max=i;
             }
         }
         ArrayList<Integer> list=new ArrayList<>();
         for(int i=0;i<cntArray.length;i++){
             if(cntArray[i]==cntArray[max]){
                 list.add(i);
             }
         }
         Collections.sort(list);
         answer=new int[list.size()];
         for(int i=0;i<list.size();i++){
             answer[i]=list.get(i)+1;
         }
         return answer;
     }
 }

3. 결과

실행결과 실패. 테스트 2, 3, 4를 제외하고는 모두 틀렸다.

4. 문제점

1, 2번 학생은 자신의 패턴(j)순회가 끝나면 다시 처음으로 돌아가 반복하지만, 3번째 학생은 반복하는 코드가 없다.

👊 두 번째 도전

1. 설계

  1. 두번째 for문에서 패턴 최댓값인 10으로 제한하는 것이 아니라 person[i].length로 자신의 패턴 길이만큼 반복하게 한다.
  2. 마지막 문제가 아닌데 패턴 순회(j)가 마지막에 도달했을 경우 다시 처음부터 순회하게 한다.

2. 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.Arrays;
import java.util.Collections;
/**
 *
 * @author HEESOO
 *
 */
 class Solution {
     public int[] solution(int[] answers) {
         int[] answer = {};
         int[][] person={{1,2,3,4,5},
                         {2,1,2,3,2,4,2,5},
                         {3,3,1,1,2,2,4,4,5,5}
                       };//제일 긴 3번이 10개임
         int[] cntArray=new int[3];
         int q=0;
         int cnt=0;
         for(int i=0;i<person.length;i++){
             for(int j=0;j<person[i].length;j++){
                 if(person[i][j]==answers[q]){//맞았으면
                     cnt++;
                 }
                 if(q==answers.length-1){//마지막 문제이면
                     cntArray[i]=cnt;
                     cnt=0;
                     q=0;
                     break;
                 }
                 else if(j==person[i].length-1){//마지막 문제가 아닌데 j가 끝났을 경우 다시 처음부터
                    j=-1;
                 }
                 q++;
             }
         }
         int max=0;
         for(int i=1;i<cntArray.length;i++){
             if(cntArray[i]>cntArray[max]){
                 max=i;
             }
         }
         ArrayList<Integer> list=new ArrayList<>();
         for(int i=0;i<cntArray.length;i++){
             if(cntArray[i]==cntArray[max]){
                 list.add(i);
             }
         }
         Collections.sort(list);
         answer=new int[list.size()];
         for(int i=0;i<list.size();i++){
             answer[i]=list.get(i)+1;
         }
         return answer;
     }
 }
  • int[][] person: 3명의 정답 패턴을 저장한 이차원 배열이다. 처음에는 각 학생별로 일차원배열에 저장할까했는데, 각각 선언하면 for문에서 3명을 호출하기 애매하여 이차원 배열을 이용하였다.
  • int[] cntArray: 3명의 학생들의 정답수를 저장한다.
  • int q: answers배열을 순회하기 위한 인덱스이다.
  • int cnt: 각 학생별 정답수를 세는 변수이다.
  • int max: 가장 많이 맞힌 학생의 인덱스 번호를 저장한다.
  • ArrayList list: 가장 많이 맞힌 학생이 여러명일 경우, 그것이 몇명이 될 지 알 수 없기 떄문에 초기 할당이 필요없는 ArrayList를 이용한다.

3. 코드 설명

첫번째 for문에서 학생별로 순회할 수 있게 하고, 두번째 for문에서는 그 학생의 패턴을 반복한다.
문제를 맞혔으면 cnt를 증가하고, 마지막 문제까지 풀면 cntArray에 정답수를 넣은 후 다음 학생을 위해 q와 cnt를 초기화한다.
아직 문제가 남았는데 패턴이 끝났다면 j=-1로 초기화하여 다시 반복한다.
3명의 정답수를 모두 세었으면 최댓값을 가진 학생이 누구인지 찾아 max에 학생의 인덱스 번호를 저장한다.
이때 1등이 여러명일 수 있으므로 ArrayList를 이용하여 최댓값을 가진 학생들의 인덱스를 모두 저장한다. 이후 오름차순으로 정렬하여 리턴한다.

4. 결과

실행결과 🤟 성공 🤟

👏 해결 완료!

학생들의 정답수를 세는 것은 어렵지 않았지만, 의외로 중복되는 1등이 있을 경우 모두 찾아 오름차순으로 정렬하는 것이 고역이었다. 배열만 사용해서 문제를 해결할 수 있을 것 같았는데 마지막에 ArrayList를 쓰니까 어색하다. 무언가 ArrayList는 거하게 써야할 것 같은데^ㅠ^.
다른 사람들은 어떻게 풀었는지 코드를 읽어보았는데, 굳이 이중for문을 돌리지 않고 한번 answers를 읽을 때 3명을 모두 비교하여 푼 사람들이 훨씬 많았다. 나는 사람을 기준으로 코드를 작성했다면, 다른 사람들은 문제를 기준으로 푼 것 같다. 그게 더 훨씬 효율성에서 좋은 것 같다.

참고