본문 바로가기
Algorithm/프로그래머스 고득점 Kit

[스택/큐] 기능개발 - Java코드

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

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

문제

 

이해

문제를 상세히 읽어보면 각각의 일률을 구할 수 있고,

들어온 순서대로 종속적인 업무이기 때문에, 앞에서 배포가 되지않으면 뒤에 업무가 완성되어도 배포할 수 없다.

이 문제는 선입 선출로 순서배포가 일어나는 구조이기때문에, 스택이아닌 큐 자료구조를 이용한다.

일률을 큐에 저장하고 peek값에 일률보다 작거나 같은것들을 count해주면서 함께 배포할 작업의 수를 저장해주면 된다. 

 

설계

큐에 저장할 일률은 소수점이 조금이라도 있는경우, 배포일은 전부 올림처리 해주어야 하므로 Math.ceil 메소드를 쓰자.

큐에 있는 작업을 remove해도 상관은 없지만, 굳이 정리할 필요가 없이, 한번의 for문으로 해결해줄 수 있다. 

+

반환값은 int[] 배열로 반환해야 하지만, 길이를 특정할 수 없으므로, List로  add해주면서 동적으로 추가해주어야한다.

마지막에 List객체를 반환 하고자하는 Array 객체로 변환시켜주는 작업이 필요하다.

 

풀이

import java.util.*;
class Solution {
    public int[] solution(int[] p, int[] s) {
    	// 일률 저장
        Queue<Integer> q = new LinkedList<>();
        for (int i=0;i<p.length;i++)
            q.add((int) Math.ceil((100.0 - p[i]) / s[i]));
        // 배포 개수 결과 저장
        List<Integer> res = new ArrayList<>();
        int cnt=0,top=q.peek();
        for (Integer i : q) {
            if(top>=i)
                cnt++;
            else{
                res.add(cnt); // 결과저장
                top = i; // 새로운 기준 top
                cnt=1;
            }
        }
        res.add(cnt); // 마지막 원소 추가

        // 결과 반환할 자료형으로 변환 (list -> array)
        int[] answer = new int[res.size()];
        for(int i=0;i<res.size();i++)
            answer[i] = res.get(i);

        return answer;
    }
}

for문 한 사이클에 끝나는 문제이지만, 

문제를 잘못이해하면, 오류에 빠지기 쉽다.

선행작업에 종속적이라는걸 생각하고, 코드를 구체화 해야한다.

+

마지막 List결과를 Array로 변환하는 작업은 한 stream api를 이용해 한줄로 만들 수 있다.

return res.stream().mapToInt(i->i).toArray(); // 결과 List 배열로 변환 (간소화시키지만, 느림)

하지만, 훨씬 느려지기 때문에, 정석적으로 for을 통해 저장해서 반환해주었다.