Algorithm & Data Structures/Programers

Lv 2. 서버 증설 횟수

Geisha 2025. 3. 11. 22:22

 

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

 

📌 자바(Java)로 푸는 서버 증설 횟수 문제 풀이 🚀

 

🔎 문제 개요

 

이 문제는 프로그래머스 - 서버 증설 횟수 문제입니다.

주어진 시간별 플레이어 수(players[]) 를 기준으로

한 대의 서버가 감당할 수 있는 최대 인원(m)과

증설 시 적용되는 지속 시간(k)을 고려하여

필요한 최소 서버 증설 횟수를 구하는 문제입니다.

 


💡 예제 입력

int[] players = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 
                 110, 120, 130, 140, 150, 160, 170, 180, 
                 190, 200, 210, 220, 230, 240};
int m = 10;
int k = 3;

💡 예제 출력

30

총 30번 서버 증설이 필요합니다.

 


🛠 알고리즘 접근 방식

 

이 문제를 해결하기 위해 그리디 알고리즘(Greedy) + 시뮬레이션을 활용합니다.

 

✏️ 주요 고려 사항

 

각 시간(i)마다 필요한 서버(nowNeed)와 기존 서버(nowCom)를 비교

기존 서버(nowCom)로 감당이 안 되는 경우, 부족한 만큼 서버 증설

증설된 서버는 k시간 동안 지속 적용

최종적으로 23시간까지의 누적 증설 횟수를 반환

 


🔹 Java 코드 해설

import java.util.*;

class Solution {
    public int solution(int[] players, int m, int k) {
        int[][] server = new int[2][24];
        Arrays.fill(server[0], 0); // 현재 서버 대수
        Arrays.fill(server[1], 0); // 누적 증설 횟수

        for (int i = 0; i < 24; i++) {
            int nowNeed = players[i] / m; // 현재 필요한 서버 수
            int nowCom = server[0][i];    // 현재 가동 중인 서버 수

            if (nowNeed > nowCom) { // 증설이 필요한 경우
                int upgrade = nowNeed - nowCom;
                server[1][i] = (i == 0) ? nowNeed : server[1][i - 1] + upgrade;

                // 증설된 서버를 k시간 동안 유지
                for (int j = i; j < i + k; j++) {
                    if (j <= 23) {
                        server[0][j] += upgrade;
                    } else {
                        break;
                    }
                }
            } else { // 증설이 필요 없는 경우
                server[1][i] = (i == 0) ? nowNeed : server[1][i - 1];
            }
        }

        return server[1][23]; // 마지막 시간(23시)까지의 누적 증설 횟수 반환
    }
}

 

 


🔍 코드 설명

 

📌 1. 서버 정보 배열 정의

int[][] server = new int[2][24];
Arrays.fill(server[0], 0); // 현재 가동 중인 서버 대수
Arrays.fill(server[1], 0); // 누적 증설 횟수

server[0][i] : i시간에 현재 운영 중인 서버 대수

server[1][i] : i시간까지의 누적 증설 횟수

 


📌 2. 각 시간별 필요한 서버 개수 계산

int nowNeed = players[i] / m; // 현재 필요한 서버 수
int nowCom = server[0][i];    // 현재 가동 중인 서버 수

players[i] / m : 한 대의 서버(m)가 감당할 수 있는 인원을 기준으로

i시간에 필요한 서버 수(nowNeed) 계산

 


📌 3. 서버 증설이 필요한 경우

if (nowNeed > nowCom) { // 증설 필요
    int upgrade = nowNeed - nowCom;
    server[1][i] = (i == 0) ? nowNeed : server[1][i - 1] + upgrade;

    // 증설된 서버를 k시간 동안 유지
    for (int j = i; j < i + k; j++) {
        if (j <= 23) {
            server[0][j] += upgrade;
        } else {
            break;
        }
    }
}

현재 가동 중인 서버가 부족한 경우(nowNeed > nowCom)

부족한 만큼(upgrade = nowNeed - nowCom) 서버 추가

누적 증설 횟수(server[1][i])를 갱신

증설된 서버는 k시간 동안 유지

 


📌 4. 서버 증설이 필요 없는 경우

else {
    server[1][i] = (i == 0) ? nowNeed : server[1][i - 1];
}

증설이 필요 없는 경우, 기존 누적 증설 횟수를 유지

 


📌 5. 최종 답 반환

return server[1][23]; // 마지막 시간(23시)까지의 누적 증설 횟수 반환

23시까지의 누적 증설 횟수를 반환

 


🔥 시간 복잡도 분석

연산 최악의 경우 수행횟수 시간 복잡도
for 루프 (24시간 순회) 24 O(24)
for 루프 (증설된 서버 적용) k * 24 O(24k)
총합   O(24k) ≈ O(1) (k ≤ 24이므로 상수 시간 복잡도)

매우 빠른 O(1) 알고리즘으로 실시간 처리 가능!

 


🏆 정리

 

✅ 핵심 포인트

 

각 시간별 필요한 서버 수를 계산하고 기존 서버와 비교

부족한 경우, 추가 서버를 k시간 동안 적용

O(1) 수준의 빠른 알고리즘으로 실시간 처리 가능


이 글이 도움이 되셨다면 좋아요와 공유 부탁드립니다!