Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions dohun/week3/ProgrammersMenuRenewal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import java.util.*;

class ProgrammersMenuRenewal {

private void combination(String order, int courseSize, int index, StringBuilder current, Map<String, Integer> countMap) {
// 조합의 길이가 코스 사이즈와 같아지면 빈도수 맵에 추가
if(current.length() == courseSize) {
countMap.put(current.toString(), countMap.getOrDefault(current.toString(), 0) + 1);
return;
}

// 조합 생성
for(int i = index; i < order.length(); i++) {
// 현재 문자 추가
current.append(order.charAt(i));

// 재귀 호출로 다음 문자 추가
combination(order, courseSize, i + 1, current, countMap);

// 백트래킹: 마지막 문자 제거
current.deleteCharAt(current.length() - 1);
}
}

public String[] solution(String[] orders, int[] course) {
// 최종 결과를 담을 리스트
List<String> answer = new ArrayList<>();

// 조합을 만들 때 순서가 다르면 다른 조합으로 인식되기 때문에 각 주문을 알파벳 순서로 정렬
// 예: "CBA" -> "ABC" 로 변환
for (int i = 0; i < orders.length; i++) {
char[] arr = orders[i].toCharArray();
Arrays.sort(arr);
orders[i] = new String(arr);
}

// 각 코스 사이즈에 대해 조합 생성 및 빈도수 계산
for (int courseSize : course) {
Map<String, Integer> countMap = new HashMap<>();

// 각 주문에 대해 조합 생성
for (String order : orders) {
// 주문의 길이가 코스 사이즈보다 작으면 조합 생성 불가
if (order.length() < courseSize) {
continue;
}
// 조합 생성
combination(order, courseSize, 0, new StringBuilder(), countMap);
}

int maxCount = 0;
// 가장 많이 등장한 조합의 빈도수 찾기
for (int count : countMap.values()) {
maxCount = Math.max(maxCount, count);
}

// 가장 많이 등장한 조합이 2번 이상 등장한 경우에만 결과에 추가
if (maxCount < 2) {
continue;
}

// 최대 빈도수와 같은 조합들을 결과에 추가
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
if (entry.getValue() == maxCount) {
answer.add(entry.getKey());
}
}
}

// 결과를 알파벳 순서로 정렬
Collections.sort(answer);

return answer.toArray(new String[0]);
}
}
35 changes: 35 additions & 0 deletions dohun/week3/ProgrammersServerScaling.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import java.util.*;

class ProgrammersServerScaling {
public int solution(int[] players, int m, int k) {
int n = players.length; // 24
// expire[t] : 시각 t에 운영이 끝나는 서버 개수
int[] expire = new int[n + k + 1];

int activeServerCount = 0; // 현재 시각에 운영 중인 서버 수
int answer = 0; // 총 증설 횟수

for (int t = 0; t < n; t++) {
// 1. 이 시각에 끝나는 서버 제거
activeServerCount -= expire[t];

// 2. 이 시각에 필요한 서버 수 (floor 나눗셈!)
int requiredServerAmount = players[t] / m;

// 3. 부족하면 그만큼 서버 증설
if (requiredServerAmount > activeServerCount) {
int addServerCount = requiredServerAmount - activeServerCount; // 새로 증설해야 하는 서버 수
answer += addServerCount;
activeServerCount += addServerCount;

// 지금 증설한 서버들은 t ~ t+k-1 동안 운영되고,
// t+k 시각부터는 빠지므로 만료 시각을 t+k로 기록
if (t + k < expire.length) {
expire[t + k] += addServerCount;
}
}
}

return answer;
}
}
88 changes: 88 additions & 0 deletions dohun/week5/ProgrammersDelivery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import java.util.*;

class Solution {

// 하나의 연결 정보 (다음 마을 번호, 그 마을까지 걸리는 시간)
static class Node implements Comparable<Node> {
int to; // 도착 마을 번호
int cost; // 이동에 걸리는 시간(거리)

Node(int to, int cost) {
this.to = to;
this.cost = cost;
}

// 우선순위 큐에서 cost가 작은 순으로 나오도록 정렬 기준 설정
@Override
public int compareTo(Node o) {
return this.cost - o.cost;
}
}

public int solution(int N, int[][] road, int K) {

// 1. 그래프 초기화
// graph[i] = i번 마을에서 갈 수 있는 (도착 마을, 비용) 리스트
List<List<Node>> graph = new ArrayList<>();

for (int i = 0; i <= N; i++) {
graph.add(new ArrayList<>());
}

// 도로 정보는 양방향이므로 둘 다 추가
for (int[] r : road) {
int a = r[0]; // 시작 마을
int b = r[1]; // 도착 마을
int c = r[2]; // 이동 비용(시간)

graph.get(a).add(new Node(b, c));
graph.get(b).add(new Node(a, c));
}

// 2. 최단 거리 테이블(dist)
// dist[i] = 1번 마을에서 i번 마을까지의 "현재까지 알려진 최단시간"
int[] dist = new int[N + 1];
Arrays.fill(dist, Integer.MAX_VALUE); // 처음엔 모든 마을이 무한히 멀다고 가정
dist[1] = 0; // 1번 마을에서 1번 마을까지의 거리는 0

// 3. 다익스트라를 위한 우선순위 큐 (비용이 가장 적은 노드부터 탐색)
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(1, 0)); // 시작점(1번 마을)

// 4. 다익스트라 알고리즘 시작
while (!pq.isEmpty()) {

// 현재까지 비용이 가장 적은 노드 꺼냄
Node cur = pq.poll();

int currentVillage = cur.to; // 현재 마을
int currentCost = cur.cost; // 1번 → 현재 마을까지 걸리는 시간

// 이미 더 짧은 경로가 있다면 이 노드는 무시(가지치기)
if (currentCost > dist[currentVillage]) continue;

// 현재 마을에서 갈 수 있는 이웃 마을들을 확인
for (Node next : graph.get(currentVillage)) {

int nextVillage = next.to;
int nextCost = currentCost + next.cost; // 현재 비용 + 다음 마을로 가는 비용

// 지금 발견한 경로(nextCost)가 기존 dist보다 더 짧으면 업데이트
if (nextCost < dist[nextVillage]) {
dist[nextVillage] = nextCost;
pq.add(new Node(nextVillage, nextCost)); // 큐에 새로운 정보 넣기
}
}
}

// 5. 최종적으로 dist 배열 중 K 이하인 마을의 개수를 센다
int answer = 0;
for (int i = 1; i <= N; i++) {
if (dist[i] <= K) {
answer++;
}
}

return answer;
}
}
41 changes: 41 additions & 0 deletions dohun/week5/ProgrammersHotelRoom.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import java.util.*;

class Solution {

public int solution(String[][] book_time) {
// 1. 시간을 모두 분 단위로 변환
int[][] times = new int[book_time.length][2];

for (int i = 0; i < book_time.length; i++) {
times[i][0] = toMinute(book_time[i][0]); // 시작 시간
times[i][1] = toMinute(book_time[i][1]); // 종료 시간
}

// 2. 시작 시간 기준 오름차순 정렬
Arrays.sort(times, (a, b) -> a[0] - b[0]);

// 3. Min-Heap: 방이 언제 비는지(= 종료 + 10분)
PriorityQueue<Integer> pq = new PriorityQueue<>();

for (int[] t : times) {
int start = t[0];
int end = t[1] + 10;

// 4. 가장 빨리 비는 방이 현재 예약 시작보다 먼저 비면 재사용
if (!pq.isEmpty() && pq.peek() <= start) {
pq.poll();
}

// 5. 새 예약 배정 (혹은 재사용된 방 업데이트)
pq.add(end);
}

return pq.size();
}

// HH:MM → 총 분(minute)으로 변환하는 함수
private int toMinute(String time) {
String[] split = time.split(":");
return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
}
}