안녕하세요, 스코리아입니다.
오늘은 자바(Java)의 Queue를 이용한 프로그래머스 Lv.2 다리를 지나는 트럭 문제를 풀어보겠습니다.
문제가 Queue를 사용하기에 너무 적합하고 깔끔한 문제라 가져와 보았습니다.
문제 설명
https://school.programmers.co.kr/learn/courses/30/lessons/42583
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
- 트럭은 한 번에 1만큼의 거리를 이동할 수 있습니다. 즉, 트럭 한 대가 길이 bridge_length의 다리를 건너기 위해서는 bridge_length만큼의 시간이 필요합니다.
- 트럭의 크기는 1입니다. 즉, 길이 bridge_length인 다리 위에 올라갈 수 있는 트럭의 수는 최대 bridge_length 대입니다.
- 다리는 '일 차선 다리'입니다. 한 번에 한대의 트럭밖에 건널 수 없습니다.
- 모든 트럭이 다리를 건넜다는 것은 다리 위에 트럭이 한대도 남아있지 않음을 뜻합니다.
- 한 트럭이 빠져나감과 동시에 다른 트럭이 다리 위에 올라올 수 있습니다. 다리가 견딜 수 있는 최대 weight만 잘 고려하면 됩니다.
트럭이 나가고 들어오는 과정이 유기적으로 필요하기 때문에 자바의 Queue 구조를 이용하면 비교적 간단하게 풀 수 있습니다.
문제에 나와있는 예시를 토대로 설명해 보겠습니다.
bridge_length | weight | truck_weights | return |
2 | 10 | [7,4,5,6] | 8 |
- 우선 bridge_length가 2이기 때문에 다리 위에는 최대 2개의 트럭밖에 오지 못합니다.
- 초기(1초가 되는 시점)에 트럭이 한 대 올라가 있어야 하므로, queue 값을 0 7로 세팅하고 시작하겠습니다.
- 여기서 0은 무게 0kg , 7은 트럭 무게 7kg을 뜻합니다. 즉, 0은 트럭이 없는 곳을 뜻합니다.
- 다리가 버틸 수 있는 최대 무게 weight는 10이라고 합니다.
트럭이 오른쪽에서 들어와서, 트럭이 왼쪽으로 한 칸씩 이동하여 다리를 빠져나간다고 생각하면 이해하기 편합니다.
- [1초] 0 7 (다리 위에 7kg 트럭이 진입한 상태)
- [2초] 7 0 (7kg 트럭이 다리 한 칸 앞으로 감. 단, 다음 트럭이 4kg이므로 동시에 올라올 수 없음. 7 + 4 > 10)
- [3초] 0 4 (7kg 트럭이 빠지고 4kg 트럭이 올라옴)
- [4초] 4 5 (4kg 트럭이 다리 한 칸 앞으로 감. 다음 트럭이 5kg이므로 동시에 올라올 수 있음. 4 + 5 < 10)
- [5초] 5 0 (4kg 트럭이 빠지고 5kg 트럭이 다리 한 칸 앞으로 감. 다음 트럭이 6kg이므로 동시에 올라올 수 없음. 5 + 6 > 11)
- [6초] 0 6 (5kg 트럭이 빠지고 6kg 트럭이 올라옴)
- [7초] 6 (6kg 트럭이 다리 한칸 앞으로 감. 다음 트럭이 없음)
- [8초] (6kg 트럭이 빠짐. 다리 위가 비었음 => 종료)
여기서 중요한 점은, 트럭이 없는 곳은 0kg으로 설정해주어야 한다는 것입니다. 단, 와야 할 '다음 트럭'이 없을 경우, 0을 넣지 않습니다. 그래야 다리에 모든 트럭이 빠져나갔는지 (queue가 비었는지) 확인할 수 있습니다.
풀이 과정
import java.util.*;
class Solution {
public int solution(int bridge_length, int weight, int[] truck_weights) {
Queue q = new LinkedList();
// 0번째 트럭을 올릴거기 때문에 bridge_length - 1 만큼 0으로 채워줌
for(int i=0;i<bridge_length-1;i++){
q.add(0);
}
// 현재 다리에 있는 트럭 무게
int current_w = truck_weights[0];
// 0번째 트럭을 다리 위에 올리기
q.add(current_w);
int answer = 1; // 0번째 트럭이 이미 올라갔으므로 시간 1부터 시작
int index = 1; // 0번째 트럭이 이미 올라갔으므로 다음 트럭 index는 1부터 시작
while(!q.isEmpty()){
answer++; // 시간 1 증가
int removed = (int) q.poll(); // 빠져나갈 트럭 1대 제거
current_w -= removed; // 현재 다리의 트럭무게에서 제거된 트럭 무게 제거
// 남은 트럭이 존재할 경우 (올라가야할 트럭이 남아있을 경우)
if(index < truck_weights.length){
// 현재 다리에 있는 트럭무게 + 다음에 올라갈 트럭 무게 <= 다리가 버틸 수 있는 무게
if(current_w + truck_weights[index] <= weight){
current_w += truck_weights[index]; // 다음 트럭 무게 추가
q.add(truck_weights[index]); // queue 에 다음 트럭 추가
index++; // index 증가
}else{
q.add(0); // 다음 트럭이 오지 못했으므로, 0 추가 (다음 트럭이 다음번에 와야하므로)
}
}
}
return answer;
}
}
- q 이름을 가진 Queue를 만들어줍니다.
- 처음 1 시간에는 0번째 트럭이 무조건 올라가 있어야 합니다. 그러므로, queue에 bridge_legnth-1만큼 0으로 채워 넣고, 0번째 트럭의 무게를 queue에 넣습니다.
- current_w 변수는 현재 다리에 있는 트럭들의 총무게를 뜻합니다. 현재 0번째 트럭이 올라가 있으므로, current_w는 0번째 트럭의 무게입니다.
- answer 변수는 시간(초)을 뜻합니다. 현재 0번째 트럭이 올라가 있으므로, 시간이 1인 상태입니다.
- index 변수는 다음 트럭 무게(truck_weights)의 index를 뜻합니다. 현재 0번째 트럭이 올라가 있으므로, 다음 트럭 무게의 index는 1번째 트럭입니다.
- Queue에 값이 없으면 모든 트럭이 다리를 건너서, 다리에 아무 트럭도 없는 상태를 뜻합니다. 그러므로 q가 비어있지 않을 때까지 while 문을 돌립니다.
[While문 풀이]
- Queue의 poll을 이용하여 맨 앞에 있는(빠져나갈) 트럭(혹은 0kg 무게)을 제거합니다. 이런 행동은 1의 시간이 소비됩니다. 그러므로 answer에 1만큼 더합니다.
- 현재 다리의 트럭 무게(current_w)에서 방금 제거된 트럭 무게(removed)를 빼줍니다.
남은 트럭이 존재할 경우. 즉 올라가야 할 트럭이 남아있는 경우 (If문)
- " 현재 다리에 있는 트럭 무게(current_w) + 다음에 올라가야 할 트럭 무게 (truck_weights[index]) <= 다리가 버틸 수 있는 무게 " 조건이 만족되는 경우 다음 트럭이 들어올 수 있습니다. 만족하는 경우, 다음 트럭 무게를 current_w 변수에 추가하고, queue에 다음 트럭 무게를 추가합니다. 그리고 다음 트럭 무게의 index의 값을 1만큼 증가시킵니다.
- 조건이 만족하지 않은 경우, 다음 트럭이 들어오지 못함을 뜻합니다. 즉, 다음번에 트럭이 와야 할 일이 있으므로, Queue에 0을 추가해 줍니다.
위쪽의 예시에서 알아봤듯이, 이 while문을 통해 Queue에 아무 값도 없을 때까지 반복한다면, 다리에 아무 트럭이 없으면 while 문이 종료되어, 얼마나 시간이 걸렸는지 answer 값을 파악할 수 있습니다.
실행 결과
- 대부분의 테스트는 0~1ms 정도의 빠른 속도를 보여줍니다. 다만 일부 테스트는 13ms, 43ms처럼 튀는 곳도 있습니다.
- 다른 분들의 풀이를 보니, 1초일 때의 초기값을 설정하지 않고, for문 안에 while문을 사용하여 풀이하신 모습을 보았습니다. 이럴 경우 조금 더 느린 속도를 보여줍니다.
지금까지 자바(Java)의 Queue를 활용한 프로그래머스 '다리를 지나는 트럭' 문제에 대해서 알아보았습니다.
읽어주셔서 감사합니다.
'JAVA > 문제 풀이' 카테고리의 다른 글
[프로그래머스] 여행 경로 문제 (Java DFS 풀이) (1) | 2024.06.30 |
---|---|
[프로그래머스] 의상 문제 (Java Hash 풀이) (1) | 2023.09.04 |
[프로그래머스] 완주하지 못한 선수 문제 (Java Hash 풀이) (3) | 2023.08.27 |
[프로그래머스] 베스트앨범 문제 (Java Hash 풀이) (2) | 2023.08.20 |