복잡한뇌구조마냥

[코딩테스트 + JAVA] 기능개발 - 프로그래머스 Lv.2 본문

공통/알고리즘 및 코테

[코딩테스트 + JAVA] 기능개발 - 프로그래머스 Lv.2

지금해냥 2025. 7. 2. 15:10

🔗 문제 링크

프로그래머스 - 기능개발


🧠 문제 요약

  • 각 기능의 개발 진도(progresses)와 개발 속도(speeds)가 주어짐
  • 매일 각 기능은 자신의 개발 속도만큼 진도가 진행됨
  • 앞의 기능이 완료되지 않으면 뒤의 기능은 배포할 수 없음
  • 한 번에 배포되는 기능의 개수를 배열로 반환

💡 풀이 전략

  1. 남은 작업 일수 계산: 각 기능이 100%가 되기까지 걸리는 일수를 계산
  2. 배포 묶음 처리: 앞에서부터 순차적으로 비교하면서, 앞 기능보다 늦게 끝나는 기능은 함께 배포
  3. 결과 리스트로 정리 후 배열 반환

📌 주요 포인트

  • Math.ceil((100.0 - progress) / speed)를 이용해 잔여일 계산
  • List를 사용해 유동적인 결과 저장
  • 스트림(stream().mapToInt().toArray())으로 리스트를 배열로 변환

🗒️풀이 1 - Stack을 활용한 역순 잔여일 계산 (solution)

  • 💡 핵심 아이디어
    • 작업 완료일을 뒤에서부터 계산해 Stack에 저장
    • Stack을 pop하면서 앞의 작업보다 빨리 끝나는 작업은 함께 배포 처리

✅ 코드

public static int[] solution(int[] progresses, int[] speeds) {
    List<Integer> answer = new ArrayList<>();
    Stack<Integer> stack = new Stack<>();

    for (int i = progresses.length - 1; i >= 0; i--) {
        int day = (int) Math.ceil((100.0 - progresses[i]) / speeds[i]);
        stack.push(day);
    }

    int count = 1;
    int max = stack.pop();

    while (!stack.empty()) {
        int day = stack.pop();
        if (day <= max) {
            count++;
        } else {
            answer.add(count);
            count = 1;
            max = day;
        }
    }

    answer.add(count);
    return answer.stream().mapToInt(Integer::intValue).toArray();
}
  • 📌 포인트
    • 뒤에서부터 Stack으로 처리하여 비교 기준을 유동적으로 관리
    • Stack이기 때문에 가독성은 조금 떨어질 수 있음

🗒️풀이 2 - 순차 비교 + 최대일 갱신 방식 (solution2)

✨ 이 풀이가 나중에 개선한 방식입니다.

💡 핵심 아이디어

  • 앞에서부터 진행하며 각 작업의 남은 일수를 구함
  • 현재 기준일(max)보다 빨리 끝나는 작업은 함께 배포

✅ 코드

public int[] solution2(int[] progresses, int[] speeds) {
    List<Integer> answer = new ArrayList<>();
    int count = 1;
    int max = (int) Math.ceil((100.0 - progresses[0]) / speeds[0]);

    for (int i = 1; i < progresses.length; i++) {
        int day = (int) Math.ceil((100.0 - progresses[i]) / speeds[i]);
        if (day <= max) {
            count++;
        } else {
            answer.add(count);
            count = 1;
            max = day;
        }
    }

    answer.add(count);
    return answer.stream().mapToInt(Integer::intValue).toArray();
}
  • 📌 포인트
    • 잔여일을 기준으로 단순 비교하여 직관적으로 처리
    • Stack 없이도 깔끔하게 로직 구현 가능
    • ✨ 발표나 설명 시 구조를 설명하기 쉬움

🔍 비교 및 회고

항목 풀이 1 (solution) 풀이 2 (solution2)
구조 Stack 역순 처리 순차 비교
가독성 다소 낮음 높음
기준 변경 Stack에서 pop으로 처리 max 값을 갱신
개선 포인트 구조적 접근 실용적이고 직관적
  • 초기에는 Stack 방식으로 구현했지만, 후에 개선된 방식이 훨씬 명확
  • Math.ceil 사용 시 실수 연산(100.0) 중요
  • 리스트를 stream().mapToInt()로 배열 변환하는 방식도 일관성 있게 사용
LIST