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

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

남건욱 2023. 11. 1. 12:55
반응형
40. 실패율

문제

import java.util.*;

class Solution {
    public int[] solution(int N, int[] stages) {
        Map<Integer, Double> map = new HashMap<>();
        
        for(int i=1; i<=N; i++){
            double total = 0;
            double fail = 0;
            for(int j=0; j<stages.length; j++){
                if(i <= stages[j]) total++;
                if(i == stages[j]) fail++;
            }
            if(total == 0 && fail == 0) total = 1;
            map.put(i, fail/total);
        }
        
        int[] answer = new int[N];
        for(int i=0; i<N; i++){
            double max = -1;
            int rKey = 0;
            for(int key : map.keySet()){
                if(max < map.get(key)){
                    max = map.get(key);
                    rKey = key;
                }
            }
            answer[i] = rKey;
            map.remove(rKey);
        }
        
        return answer;
    }
}

<작성한 코드>

우선 HashMap하나를 생성해 줬다. 목적은 키값은 스테이지 번호, 벨류는 실패율을 저장할 것이다. 중첩 for문을 사용하였고, 첫 for문에서는 스테이지 번호를 1부터 N까지 반복했다. 그리고 total은 스테이지에 도달한 수, fail은 해당 스테이지에서 실패한 수를 저장했다. 그 뒤 stages의 모든 원소를 돌며 total에는 현재 스테이지에 도달했거나 그 뒤의 스테이지에 있다면 total을 증가시켜 줬고, 현재 스테이지에 있고 아직 클리어하지 못했다면 fail을 증가시켜 줬다. 그 뒤 if문을 한번 사용해서 사용자가 스테이지에 도달한 플레이어가 없고, 실패한 플레이어도 없을 때는 total을 1로 설정해 줬다. 그 뒤 해당되는 스테이지값인 i와 값을 fail/total을 해준 뒤 넣어줬다. 이제 정수형 배열 answer을 만들어줬다. 크기는 N만큼 할당해 줬다. for문에서 max는 최대 실패율을 뜻하는 변수이고 -1로 선언해 줘서 첫 비교부터 바뀌도록 생성해 줬다. 그 뒤 forEach문으로 map에 있는 키들을 반복해서 가져왔고, if문을 사용해서 그 키의 벨류가 max보다 크다면 max에 그 값을 집어넣어 주고 rKey 변수에 key값을 넣어줬다. 그 뒤 answer [i]에 제일 큰 값을 넣어주고 map에서 그 키에 해당하는 값을 지워둔 뒤 반복하였다. 그 뒤 answer을 반환해 줬다.

 

많은 시간이 들었던 문제다. 

 

 

 

 

41. 크레인 인형 뽑기 게임

문제

import java.util.*;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;
        List<Integer> list = new ArrayList<>();
        
        for(int i=0; i<moves.length; i++){
            for(int j=0; j<board.length; j++){
                if(board[j][moves[i]-1] != 0){
                    list.add(board[j][moves[i]-1]);
                    board[j][moves[i]-1] = 0;
                    break;
                }
            }
            if(list.size() >= 2 && list.get(list.size()-1).equals(list.get(list.size()-2))){
                answer += 2;
                list.remove(list.size()-1);
                list.remove(list.size()-1);
            }
        }
     
        return answer;
    }
}

<작성한 코드>

우선 뽑은 인형을 저장할 list를 하나 만들었다. 그 뒤 moves의 길이만큼 첫 반복문을 반복해 주고, 내부에서 다시 board의 길이만큼 반복해 줬다. if문을 사용해서 모든 배열의 moves [i]-1번째의 값을 비교해서 0이 아니라면 list에 추가하고 그 값을 0으로 만들었다. 뽑았다면 break를 사용해서 반복문을 멈췄다. 두 번째 반복문이 끝나는 시점에서 비교해 준다. list에 값이 두 개 이상 들어있고, 만약 마지막원소와 마지막이전 원소의 값이 같다면 answer에 2를 더해줬다. 그 뒤 list에서 두 개의 값을 제거해 주고 answer값을 반환해 주면 된다.

 

문제만 봤을 때는 어려워 보였는데 간단한 문제였다. 10분도 안 걸렸던 것 같다.

 

 

 

42. 키패드 누르기

문제

class Solution {
    public String solution(int[] numbers, String hand) {
        String answer = "";
        int left = 10;
        int right = 12;
        
        for(int i=0; i<numbers.length; i++){
            int num = numbers[i];
            if(num == 1 || num == 4 || num == 7){
                left = num;
                answer += "L";
            } else if(num == 3 || num == 6 || num == 9){
                right = num;
                answer += "R";
            } else if(num == 2 || num == 5 || num == 8 || num == 0){
                if(num == 0) num = 11;
                
                int leftL = (Math.abs(num - left) / 3) + (Math.abs(num - left) % 3);
                int rightL = (Math.abs(num - right) / 3) + (Math.abs(num - right) % 3);
                
                if(leftL == rightL){
                    if(hand.equals("left")){
                        left = num;
                        answer += "L";
                    } else{
                        right = num;
                        answer += "R";
                    }
                } else if(leftL > rightL){
                    right = num;
                    answer += "R";
                } else if(leftL < rightL){
                    left = num;
                    answer += "L";
                }
            }
                
        }
        
        return answer;
    }
}

<작성한 코드>

간단해 보였지만 이동할 경로값을 구할 때 생각을 많이 하게 됐다. 키패드의 *은 10, #은 12로 잡고 진행하였다. 초기값은 왼쪽을 담당할 변수 left에 10, 오른쪽을 담당할 변수 right에 12를 기본값으로 주고 진행했다. 반복문으로 numbers의 길이만큼 반복해 줬다. num에는 입력해야 할 번호를 담아줬고 번호가 1,4,7이라면 왼손을 사용해야 하니 left의 값을 num으로 바꿔주고 answer에 L을 더했다. 3,6,9라면 오른손을 사용해야 하니 right의 값을 num으로 바꿔주고 answer에 R을 더했다. 만약 2,5,8,0이라면 이동경로를 구해야 했다. 만약 0이라면 num에는 11을 넣어주고 진행했다. 구하는 공식은 가로, 세로로 이동해야 하는 경로의 값을 더해줬다. 왼손에서 번호까지의 경로는 num-left를 해준 절댓값을 3으로 나눈 몫 + num-left를 해준 절대값을 3으로 나눈 나머지의 값을 더해줬다. 오른손도 같은 식으로 구해줬다. 그 뒤 두 개의 값이 같다면 왼손잡이 일 땐 left, 오른손잡이 일땐 right에 값을 넣고 문자열도 더해줬다. 만약 left가 더 길다면 오른손으로 움직여야 하니 오른손을 사용해 주고, right가 더 길다면 왼손을 사용해야 하니 왼손을 사용해 줬다. 그리고 answer을 반환하였다.

 

 

 

43. 두 개 뽑아서 더하기

문제

import java.util.*;

class Solution {
    public int[] solution(int[] numbers) {
        Set<Integer> set = new HashSet<>();
        
        for(int i=0; i<numbers.length-1; i++){
            for(int j=i+1; j<numbers.length; j++){
                set.add(numbers[i] + numbers[j]);
            }
        }
        
        
        int[] answer = new int[set.size()];
        int idx = 0;
        for(int num : set){
            answer[idx++] = num;
        }
        
        Arrays.sort(answer);
        
        return answer;
    }
}

<작성한 코드>

간단한 문제다. 중복을 피하기 위해 HashSet을 사용하였다. 중첩 반복문을 사용해서 i는 0부터 마지막 이전 값까지 반복했고, j는 i+1부터 마지막값까지 반복해 줬다. set에 두 개의 값을 더한 값을 대입해 줬다. 그 뒤 answer의 길이를 set의 길이만큼 선언해 준 뒤 answer에 값을 대입해 줬다. 그 뒤 Arrays.sort()를 사용해서 오름차순으로 정렬해 주고 answer를 반환하였다.

 

 

 

 

44. 3진법 뒤집기

문제

class Solution {
    public int solution(int n) {
        int answer = 0;
        int num = 0;
        String result = "";
        
        while(n > 0){
            num = n % 3;
            result += num;
            
            n = n / 3;
        }
    
        answer = Integer.parseInt(result, 3);
        
        return answer;
    }
}

<작성한 코드>

간단한 문제였다. 변수 num을 선언해 주고 값을 담을 문자열 result를 만들어줬다. while문을 사용해서 n이 0보다 크면 실행하게 했고 num에는 n을 3으로 나눈 나머지를 대입하고 그 값을 result에 추가해 줬다. 그 뒤 n에 n/3을 넣어주고 반복시켰다. 이렇게 되면 자동으로 뒤집어서 저장이 된다. 그다음 answer에는 Integer.parseInt(result, 3)을 사용해서 3진수인 result를 10진수로 변환한 뒤 대입해 준다. 그 뒤 answer을 저장해 주면 된다.

 

 

 

 

45. 내적

문제

class Solution {
    public int solution(int[] a, int[] b) {
        int answer = 0;
        
        for(int i=0; i<a.length; i++){
            answer += a[i] * b[i];
        }
        
        return answer;
    }
}

<작성한 코드>

간단한 문제다. a [i] * b [i] 해준 값을 answer에 넣어주기만 하면 된다. 그 뒤 반환했다.

반응형
프로필사진

남건욱's 공부기록