프로그래머스/자바 Lv2
[프로그래머스] Java Lv2. 코딩테스트 연습 > 스택/큐 > 다리를 지나는 트럭 42583
행수쌤
2024. 10. 29. 17:22
728x90
반응형
문제설명
트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 다리에는 트럭이 최대 bridge_length대 올라갈 수 있으며, 다리는 weight 이하까지의 무게를 견딜 수 있습니다. 단, 다리에 완전히 오르지 않은 트럭의 무게는 무시합니다.
접근방법
- 다리에 먼저 접근한 차량이 먼저 빠져나가니 Queue를 선택.
- 시간을 증가시키며 다리(큐)에 차량을 집어넣는 방법으로 접근.
- 다리에 들어간 차량의 시간을 알아야 빠져나오는 시간이 계산 가능하므로 큐에는 차량의 시간 정보를 입력
- 들어간 마지막 차량의 index를 변수에 집어넣고, 빠져나온 차량의 index는 큐의 size로 계산
핵심로직
- while문을 사용하여 시간(answer)을 계속해서 증가 시키며 로직 진행 : 시간복잡도 O(n)
- 큐의 맨 앞 시간에 다리 길이(빠져나오는 시간)를 합친 값이 현재 시간(answer)보다 작거나 같으면 큐에서 제거 및 무게 감소
- 다리에 다음 차량이 들어갈 수 있는 상황이면 현재 시간(answer) 입력 및 index +1
입출력 예
- bridge_length = 2
- weight = 100
- truck_wieghts = [7, 4, 5, 6]
- return = 8
코드 작성(1차)
import java.util.*;
class Solution {
public int solution(int bridge_length, int weight, int[] truck_weights) {
// 현재 다리에 올라간 트럭들의 진입 시간을 저장하는 큐
Queue<Integer> onBridgeTime = new LinkedList<>();
// 다리를 건너는 데 걸린 총 시간
int answer = 0;
// 현재 다리 위에 있는 트럭들의 총 무게
int weightSum = 0;
// truck_weights 배열을 탐색하기 위한 인덱스
int index = 0;
// 트럭이 모두 다리를 건널 때까지 반복
while(index < truck_weights.length) {
answer++; // 시간 경과
// 다리 위에 트럭이 있고, 다리의 맨 앞 트럭이 다리를 다 건넌 경우
if (!onBridgeTime.isEmpty() && onBridgeTime.peek() + bridge_length <= answer) {
// 다리에서 트럭을 내리며, 그 트럭의 무게를 다리 무게에서 빼줌
weightSum -= truck_weights[index - onBridgeTime.size()];
onBridgeTime.poll(); // 다리 큐에서 해당 트럭을 제거
}
// 다리에 트럭을 추가할 수 있는지 확인
if (onBridgeTime.size() < bridge_length && weightSum + truck_weights[index] <= weight) {
// 트럭을 다리에 추가하며 진입 시간 기록
onBridgeTime.add(answer);
// 다리 위 트럭들의 총 무게 업데이트
weightSum += truck_weights[index];
// 다음 트럭으로 이동
index++;
}
}
// 마지막 트럭이 다리를 완전히 건너는 데 필요한 시간 추가
answer += bridge_length;
return answer; // 모든 트럭이 다리를 건너는 데 걸린 총 시간 반환
}
}
큐에 시간 정보가 들어간다는 것이 직관적이지 않으니 큐에 차량 무게를 집어넣기 위해선 어떻게 하면 될까?
매 시간마다 큐에 차량 무게(차량이 안들어가는 경우 0)를 집어넣으며 처리 가능
코드 작성(2차)
import java.util.*;
class Solution {
public int solution(int bridge_length, int weight, int[] truck_weights) {
Queue<Integer> bridge = new LinkedList<>();
int answer = 0; // 경과 시간
int weightSum = 0; // 다리 위의 총 무게
int index = 0; // truck_weights 인덱스
// 다리 길이만큼 0으로 초기화하여 트럭이 없는 상태를 나타냄
for (int i = 0; i < bridge_length; i++) {
bridge.add(0);
}
while (index < truck_weights.length) {
answer++; // 시간 증가
// 다리 앞에서 나오는 트럭의 무게를 다리에서 빼줌
weightSum -= bridge.poll();
// 다음 트럭이 다리에 올라갈 수 있는지 확인
if (weightSum + truck_weights[index] <= weight) {
bridge.add(truck_weights[index]);
weightSum += truck_weights[index];
index++;
} else {
// 무게 초과 시 0을 추가하여 다리 길이 확보
bridge.add(0);
}
}
// 마지막 트럭이 다리를 완전히 건너기 위한 시간 추가
answer += bridge_length;
return answer;
}
}
728x90
반응형