프로그래머스 문제풀이/알고리즘 (JAVA)

[JAVA] 프로그래머스 알고리즘 문제풀이 - Level 1 (35~39번 문제풀이) / Level 0 (224/224)

남건욱 2023. 10. 30. 20:44
반응형
35. 다트 게임

문제

class Solution {
    public int solution(String dartResult) {
        int answer = 0;
        int[] scores = new int[3];

        int n = 0, idx = 0;
        String numStr = "";

        for(int i=0; i<dartResult.length(); i++){
            char ch = dartResult.charAt(i);

            if(ch >= '0' && ch <= '9'){
                numStr += String.valueOf(ch);
            } else if(ch == 'S' || ch == 'D' || ch == 'T'){
                n = Integer.parseInt(numStr);
                if(ch == 'S'){
                    scores[idx] = (int)Math.pow(n, 1);
                    idx++;
                } else if(ch == 'D'){
                    scores[idx] = (int)Math.pow(n, 2);
                    idx++;
                } else{
                    scores[idx] = (int)Math.pow(n, 3);
                    idx++;
                }
                numStr = "";
            } else{
                if(ch == '*'){
                    scores[idx-1] *= 2;
                    if(idx-2 >= 0) scores[idx-2] *= 2;
                } else{
                    scores[idx-1] *= -1;
                }
            }
        }

        answer = scores[0] + scores[1] + scores[2];

        return answer;
    }
}

<작성한 코드>

점수를 저장할 배열 scores를 만들어줬다. 그리고 정수형 변수 n을 만들어두고 인덱스값을 담당할 idx변수를 각각 0으로 초기화해 줬다. 또한 문자열 변수 numStr을 만들어서 중간에 변환해서 사용하였다. 반복문은 dartResult의 길이만큼 반복시켰고, 문자형 변수 ch에는 각 문자를 저장했다. 큰 if문에서는 총 3가지 경우로 나눴다. 먼저 0~9까지의 숫자인 경우, S/D/T의 문자 중 하나인 경우, */#중 하나인경우로 총 3가지로 나눴다. 우선 숫자인 경우네는 numStr에 문자열형으로 값을 저장해 줬다. 그 뒤 S/D/T 중 하나가 온다면 저장했던 문자열을 n에 정수형으로 다시 저장한다. 그 뒤 문자가 뭔지 체크하고 점수의 0번째 인덱스부터 값을 대입해 줬다. Math.pow를 사용해서 S라면 1 제곱, D라면 2 제곱, T라면 3 제곱을 해줬다. 그 뒤 idx값을 1을 증가시킨다. 그 뒤 numStr은 빈문자열로 재초기화 한다. 마지막으로 *이나 #이 온다면 이전 인덱스값에서 2를 곱해서 값을 넣어줬다. 또한 if문을 사용해서 idx-2를 했을 때 0 이상이라면, 즉 그전에 얻은 점수도 2배를 해주기 위해 조건을 걸었다. 만약 #이 나온다면 곱하기 -1을 해준 값을 넣어줬다. 그 뒤 scores 배열 안에 있는 모든 값들을 더해서 answer에 넣어주고 반환하였다.

 

 

 

36. 완주하지 못한 선수

문제

import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        Map<String, Integer> map = new HashMap<>();
        
        for(String name : participant){
            map.put(name, map.getOrDefault(name, 0) + 1);
        }
        
        for(String name : completion){
            map.put(name, map.get(name) - 1);
        }
        
        for(String key : map.keySet()){
            if(map.get(key) != 0){
                answer += key;
                break;
            }
        }
        
        return answer;
    }
}

<작성한 코드>

map을 하나 만들고 문자열, 정수를 키값으로 잡았다. 첫 forEach문에서는 선수명단에 있는 값들을 대입해줬다. getOrDefault를 사용해서 그 이름을 가진 키가 없다면 새로운 키로 등록하고, 이미 존재한다면 기존값을 1 증가시켰다. 그 뒤 두 번째 forEach문에서는 완주한 선수의 명단을 찾아서 키값이 존재하면 -1을 해준다. 그 뒤 마지막 forEach문에서는 map에 있는 키값들을 가져와서 벨류값이 0이 아닌 것들을 answer에 넣어줬다. 그 뒤 answer을 반환해 줬다.

 

37. K번째수

문제

import java.util.*;

class Solution {
    public int[] solution(int[] array, int[][] commands) {
        List<Integer> result = new ArrayList<>();
        
        for(int i=0; i<commands.length; i++){
            int start = commands[i][0] - 1; 
            int end = commands[i][1];
            int num = commands[i][2] - 1;
            
            List<Integer> list = new ArrayList<>();
            for(int j=start; j<end; j++){
                list.add(array[j]);
            }
            
            Collections.sort(list);
            result.add(list.get(num));
        }
        
        int[] answer = new int[result.size()];
        for(int i=0; i<result.size(); i++){
            answer[i] = result.get(i);
        }

        return answer;
    }
}

<작성한 코드>

정수형 리스트인 result를 생성해 주고 시작했다. 그리고 for문을 이용해서 commands의 길이만큼 반복했다. 시작 정수는 commands의 첫 번째 원소에서 -1을 해주고, 끝정수는 commands의 두 번째 원소로 지정했다. num은 해당 번째에서 -1의 인덱스에 해당하는 값을 넣어줘야 하니 commands의 세 번째 값에서 -1을 해줬다. 그 뒤 새로운 정수형 배열 list를 만들어 주고 리스트에는 start부터 end까지 반복해 가며 해당되는 정수들을 list에 추가해 줬다. 그 뒤 Collections.sort()를 사용해서 리스트를 정렬해 주고 list의 num번째에 해당하는 값을 result에 추가해 줬다. 이렇게 commands의 길이만큼 반복한 뒤 answer의 길이를 result와 같은 크기로 선언해 주고 answer에 result의 값을 넣어주고 반환했다.

 

 

 

38. 모의고사

문제

import java.util.*;

class Solution {
    public int[] solution(int[] answers) {
        List<Integer> list = new ArrayList<>();
        int[] one = {1, 2, 3, 4, 5};
        int[] two = {2, 1, 2, 3, 2, 4, 2, 5};
        int[] three = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
        int[] score = new int[3];
        
        for(int i=0; i<answers.length; i++){
            if(answers[i] == one[i%5]) score[0]++;
            if(answers[i] == two[i%8]) score[1]++;
            if(answers[i] == three[i%10]) score[2]++;
        }
        
        int max = Math.max(Math.max(score[0], score[1]), score[2]);
        
        for(int i=0; i<score.length; i++){
            if(score[i] == max){
                list.add(i+1);
            }
        }
        
        int[] answer = new int[list.size()];
        for(int i=0; i<list.size(); i++){
            answer[i] = list.get(i);
        }
        
        return answer;
    }
}

<작성한 코드>

우선 각 규칙이 1, 2, 3번 수포자에게 나열되어 있다. 각 배열에 3가지의 규칙을 나열해 두고 점수를 저장할 정수형 배열 score와 list를 만들어줬다. 그 뒤 answers의 길이만큼 for문을 반복해 주고 만약 정답과 각 인덱스% 반복수의 값이 같으면 점수에 +1씩 해줬다. 그 뒤 정수형 변수 max에 최댓값을 넣어줬다. 다음 반복문에서는 score의 각 값들이 max값과 같다면 list에 추가해 줬다. (i+1)을 해준 이유는 0번부터 시작하는 게 아닌 1번부터 시작하기 때문에 +1을 해줬다. 그 뒤 answer을 list의 크기만큼 선언해 준 뒤 값을 그대로 answer에 대입하고 반환해 줬다.

 

 

 

39. 체육복

문제

import java.util.Arrays;

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = 0;
        
        Arrays.sort(reserve);
        Arrays.sort(lost);

        answer = n - lost.length;
        

        for (int i=0; i<lost.length; i++) {
			for (int j=0; j<reserve.length; j++) {
				if (lost[i] == reserve[j]) {
					answer++;
					lost[i] = -1;
					reserve[j] = -1;
                    break;
				}
			}
		}

        for (int i=0; i<lost.length; i++) {
			for (int j=0; j<reserve.length; j++) {
				if (lost[i] - 1 == reserve[j] || lost[i] + 1 == reserve[j]) {
					answer++;
					reserve[j] = -1;
					break;
				}
			}
		}
        
        return answer;
    }
}

<작성한 코드>

우선 reserve와 lost를 오름차순으로 정렬해 줬다. 초기 answer의 값은 전체학생수에서 체육복을 잃어버린 학생수를 빼준 만큼의 값을 초기화해 줬다. 그 뒤 중첩 for문을 사용해서 도난당한 학생 중 여벌의 체육복이 있는 학생을 구한다. i는 잃어버린 학생, j는 여벌의 체육복이 있는 학생만큼 반복했다. 내부에서는 잃어버린 학생의 번호와 여분의 체육복이 있는 학생의 값이 같으면 수업을 들을 수 있는 학생수인 answer을 1 더 해주고 lost, reserve값을 -1로 초기화해줬다. 그 다음 아래 for문은 체육복을 빌릴수있는 학생을 구하기 위해 사용했다. i는 잃어버린 학생, j는 여분의 체육복이 남아있는 학생이다. 조건을 걸어서 lost에서 -1한값과 +1한값이 reserve에 있는 값과 일치하다면 체육복을 빌려준것으로 판단하고 answer에 1을 추가해주고 reserve에는 -1을 초기화 해줬다. 그 뒤 answer을 반환하였다.

반응형
프로필사진

남건욱's 공부기록