본문 바로가기

알고리즘/Lv. 2

프로그래머스 42586 기능개발 자바 풀이

728x90

난이도 : Lv. 2

풀이일 : 2410163

https://school.programmers.co.kr/learn/courses/30/lessons/42586

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제


아이디어

  • 각 기능의 배포일을 구해 days 배열에 저장한다.
  • 배열을 순회하며, 배포일에 배포할 수 있는 기능의 수를 구한다.

1차 시도 실패

import java.util.ArrayList;

class Solution {
    public int[] solution(int[] progresses, int[] speeds) {        
        
        // 각 기능 완료일
        double[] days = new double[speeds.length];
        for (int i = 0; i < speeds.length; i++) {
            double day = Math.ceil((100-progresses[i])/speeds[i]);
            days[i] = day;
        }
        
        // 배포일별 배포 기능 수
        ArrayList<Integer> list = new ArrayList<>();
        int pointer = 0;
        for (int i = 1; i < days.length; i++) {
            if (days[i] > days[pointer]) {
                list.add(i - pointer);
                pointer = i;
            }
        }
        list.add(days.length - pointer);
        
        // 형변환
        int[] answer = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            answer[i] = list.get(i);
        }
        
        return answer;
    }
}

 

코드 구성

  • days : 각 배포일을 저장할 배열, ceil을 이용하기 위해 double 자료형을 사용하였다.
  • day : 배포일 계산
  • list : 각 배포일에 배포할 수 있는 기능의 수를 구하기 위해, 크기를 선언하지 않아도 되는 ArrayList를 사용하였다.
  • pointer : 현재 배포일을 가리키는 변수로, days[pointer]보다 배포일이 작은 날을 센다.
  • days 순회가 끝난 후, 마지막 배포일에 배포되는 기능의 수를 추가적으로 기록한다.
  • 마지막으로, answer에 list 요소를 넣어 형변환을 해준다.

틀린 이유

  • double자료형에서 ceil 사용 시, 정수를 입력하면 정수 단위의 계산이 반환된다.

풀이 코드

import java.util.ArrayList;

class Solution {
    public int[] solution(int[] progresses, int[] speeds) {        
        
        // 각 기능 완료일
        double[] days = new double[speeds.length];
        for (int i = 0; i < speeds.length; i++) {
            double day = Math.ceil((100.0-progresses[i])/speeds[i]);
            days[i] = day;
        }
        
        // 배포일별 배포 기능 수
        ArrayList<Integer> list = new ArrayList<>();
        int pointer = 0;
        for (int i = 1; i < days.length; i++) {
            if (days[i] > days[pointer]) {
                list.add(i - pointer);
                pointer = i;
            }
        }
        list.add(days.length - pointer);
        
        // 형변환
        int[] answer = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            answer[i] = list.get(i);
        }
        
        return answer;
    }
}

 

코드 변화

  • Math.ceil() 내부 로직에서 100 부분을 100.0으로 설정하여, ceil 내부에 넣은 요소가 정수형이 아니라 실수형이 되도록 조정하였다.

반례

입력값 기댓값
[90, 85], [4, 5] [2]
  • ceil을 사용하고, 정수형만 넣어 계산했을 때를 잡아낼 수 있는 반례

배운점

  • double 연산에서의 ceil 사용 시, 정수와 실수 연산 차이

느낀점

  • 기초 공부를 할 때는 이런 내용들이 있어도 잘 보이지 않는 것 같다.
  • 코드 작성해보고 틀리고, 틀린 원인을 찾아가는 과정이 기초를 다지는 데에 중요하다는 것을 배울 수 있었다.