Lv 2. 서버 증설 횟수
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) 수준의 빠른 알고리즘으로 실시간 처리 가능
이 글이 도움이 되셨다면 좋아요와 공유 부탁드립니다!