반응형

이번 문제는 <모의고사>다.
"코딩 테스트 합격자 되기 자바편" 기준으로는 4번에 해당
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/42840)

프로그래머스는 블로그 게재시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다. 

문제 설명부터 너무 나를 위한 거라 마음에 들더라?
(아무도 안 믿지만 과거의 수포자)

패턴이 정확히 있고 하니까
정답 배열이랑 비교해서 맞은 개수 카운트 하면 되겠네
하고 가볍게 시작했는데
나중에 보니 가장 많은 문제를 맞힌 사람을 숫자로 표현해줘야 했다.
그게 좀 까다롭(?)다.

import java.util.*;

class Solution {
    public int[] solution(int[] answers) {
        int[] answer = {};
        
        int[] sa1 = {1, 2, 3, 4, 5}; // 5개
        int[] sa2 = {2, 1, 2, 3, 2, 4, 2, 5}; // 8개
        int[] sa3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}; // 10개
        int[] score = new int[3]; // 점수 계산용
        ArrayList<Integer> ans = new ArrayList<>();
    
        int s1 = 0, s2 = 0, s3 = 0;
        
        for (int i=0; i<answers.length; i++){
        	// 1번 학생의 패턴인 1~5 순서대로 반복하면서 비교
            if(sa1[s1]==answers[i]) {score[0]++;}
            s1++;
            if(s1==5) {s1=0;}
            
             if(sa2[s2]==answers[i]) {score[1]++;}
            s2++;
            if(s2==8) {s2=0;}
            
             if(sa3[s3]==answers[i]) {score[2]++;}
            s3++;
            if(s3==10) {s3=0;}
        }
        
        // 가장 많이 맞춘 학생의 점수 찾기
        int max = Arrays.stream(score)
                        .max().getAsInt();
        
        // 최고점과 각 학생의 점수 비교해서, 순서찾기
        // 다 같이 점수가 동일한 경우에는 어차피 1번 학생부터 add됨
        for (int i=0; i<3; i++){
            if (max == score[i]){
                ans.add(i+1);
            }
        }
        answer = ans.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
}

오 책의 예시 답안을 보니 접근방법은 나랑 비슷한데, 훨씬 더 깔끔하게 풀어내셨다.

import java.util.*;

class Solution {
    public int[] solution(int[] answers) {
        int[] answer = {};
        
        // (나랑 다른 부분) 패턴을 이렇게 2차원 배열에 넣었다.
        
        int [][] pattern ={
        	{1, 2, 3, 4, 5}, // 5개
            {2, 1, 2, 3, 2, 4, 2, 5}, // 8개
			{3, 3, 1, 1, 2, 2, 4, 4, 5, 5}; // 10개
            }
            
        // (동일) 점수 저장할 배열을 만들었다    
        int[] score = new int[3]; // 점수용
        
        // 각 수포자의 패턴과 정답이 얼마나 일치하는지를
        // for문 2개에 구성해서 표현했다.
        // 이게 핵심이니까 여기는 필요하면 책을 찾아보세요.
        
        // (동일) 가장 높은 점수를 찾고
        int max = Arrays.stream(score)
                        .max().getAsInt();
                        
        // (동일) 가장 높은 점수를 가진 사람들을 찾아서 리스트에 담는다.
        for (int i=0; i<3; i++){
            if (max == score[i]){
                ans.add(i+1);
            }
        }
        answer = ans.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
}

공부에 참고한 책 이름은 김희성 님의 "코딩 테스트 합격자 되기 자바편"입니다.

오늘의 챌린지 문제 2개를 풀면서 내가 느낀 것은

1. 어레이 리스트 할당하는 법과 >>  ArrayList<Integer> sums = new ArrayList<>();
2. 스트림 메서드를 활용하고 >> Arrays.stream(score).max().getAsInt();
3. 또 변환하는 법도 알아야 한다는 사실 >> sums.stream().mapToInt(Integer::intValue).toArray();

프로그래머스 레벨 1~3이랑 백준 실버까지는 풀어야 된다는데
할 수 있지 나 자신?! 

반응형
반응형

돌아온 코테 공부 시간
혼자서 하려니 의욕이 나지 않더라구요
그래서 찾아보니 많은 분들이 책을 보면서 하고 계셨다.
서칭해서 가장 많이 나온 건 한빛 미디어의 이것이 시리즈 중
"이것이 취업을 위한 코딩 테스트다 with 파이썬" by 나동빈이었다.
일단 나는 자바로 하기로 결심했는데 얘는 파이썬이고...
게다가 전자책 따로 사기도 도서관에서 빌리기도 귀찮아서
밀리의 서재에 들어가서 검색해봤더니 책이 꽤나 많았다.

"코딩 테스트 합격자 되기 자바편" by 김희성을 골랐다.
심지어 프로그래머스에서 제공하는 97문제나 풀어볼 수 있음!

"코딩 테스트 합격자 되기 자바편"은
책 초반에 코테를 효율적으로 분석하는 법을 먼저 알려준다.
나는 N년 전에 코테 처음 시험 볼 때도 지금도... 냅다 풀었는데 그게 아니구나^^!
1. 문제를 쪼개서 분석하라
2. 제약사항을 파악하고 나만의 테스트케이스를 추가해라
3. 입력값을 분석하라
4. 의사코드로 설계하는 연습을 해라
5. 시간 복잡도도 고려해라
대충 위와 같은 내용들인데 괜찮은 것 같다.

그리고 나서 배열, 스택과 같이 자료구조 순서대로
개념과 정의, 알아야 할 내용 등을 설명해준다.
자료구조별로 몸풀기 문제가 있는데
풀면서 유의해야 할 점들 같은 내용들도 같이 소개해준다
그리고 그 다음이 합격자가 되는 모의 테스트라고 해서,
문제를 4-5개씩 풀어볼 수 있게 해두었더라.

내용도 구성도 괜찮다고 생각해
하루에 2-3개 정도를 풀면서
까먹은 자바도 상기하고
알고리즘도 익히고 문제도 풀 계획을 세웠다.

알다시피 그렇게 꾸준 인간은 아니고
작심삼일 n번 모으기와 벼락치기로 이루어진 인간이라...
하는데까지 해보겠다.

각설하고 오늘은
"코딩 테스트 합격자 되기 자바편" 도서 기준으로는 3번이고,
프로그래머스 기준으론 월간 코드 챌린지 시즌 1에 해당하는 문제
<두 개 뽑아서 더하기> 이다.
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/68644?)

프로그래머스는 블로그 게재시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다. 

책에서는 문제풀이 권장 시간과 시간 복잡도도 알려준다.
이 문제는 권장 풀이 시간은 30분이고
시간 복잡도는 O(N^2 log(N^2)) 이다.

하지만 최대 데이터 개수가 100개라
시간 복잡도를 굳이 따지지 않아도 될 문제같다.

내 작성코드

import java.util.*;

class Solution {
    public int[] solution(int[] numbers) {
        int[] answer = {};
        
        // 그냥 Array는 개수를 지정해줘야 하는데
        // 결과값이 몇 개가 나올지 모르니까
        // 자바에서 크기가 동적으로 변경되는 ArrayList를 활용했다
        ArrayList<Integer> sums = new ArrayList<>();
        
        int x = 0;
        // 두 수를 선택하는 모든 경우의 수를 반복해서
        for (int i=0; i<numbers.length; i++){
            for (int j=i+1; j<numbers.length; j++){
                x = numbers[i]+numbers[j];
                // 더한 결과가 중복 없이 1번만 저장되도록 비교
                if (!sums.contains(x)){
                    sums.add(x);}             
            }
        }
        // ArrayList의 모든 데이터 정렬
        Collections.sort(sums);
        
        // int형 배열로 변경 후 반환한다
        answer = sums.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
}

책은 중복값이 저장되지 않는 해시셋Hashset 으로 풀었더라

 

반응형

+ Recent posts