리트코드) 743. 네트워크 딜레이 타임 (자바)
네트워크 딜레이 타임
https://leetcode.com/problems/network-delay-time/
문제 :
- k에서 출발해 모든 노드가 신호를 받을 수 있는 시간을 계산하라.
- 한 군데라도 노드에 도달할 수 없는 경우 -1 반환
- 입력값 (u, v, w)는 각각 출발지, 도착지, 소요시간으로 구성되며, 전체 노드의 개수는 n개
예시 1
- 입력: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
- 출력: 2
예시 2
- 입력: times = [[1,2,1]], n = 2, k = 1
- 출력: 1
예시 3
- 입력: times = [[1,2,1]], n = 2, k = 2
- 출력: -1
다익스트라 알고리즘
: 항상 노드 주변의 최단 경로만을 택하는 대표적인 그리디 알고리즘 중 하나
다익스트라 알고리즘 구현시 우선순위 큐를 적용하면 시간복잡도가 O((V + E) log V)가 된다.
최단 경로 찾기시 자주 쓰임
판별할 사항
- 모든 노드가 신호 받는데 걸리는 시간 => 시간 순으로 저장하기 위해 우선순위 큐 사용
- 모든 노드에 도달할 수 있는지 여부 (없으면 -1) => 결과 변수가 노드의 수와 같은지 확인
특징
- Map.Entry를 사용하면 목록형 map을 반복문을 순회하듯 사용할 수 있다.
- Map.Entry.comparingByValue()를 사용하여 정렬 순서를 지정할 수 있다.
풀이
-
담기 [2,1,1]를 Map<Integer, Map<Integer, Integer»에 담기
=> key 2 / k: 1, v: 1 -
우선순위 큐 준비
Map.Entry.comparingByValue()를 사용하면 Value값을 기준으로 오름차순으로 정렬함
new AbstractMap.SimpleEntry<>(k, 0) // k부터 시작이고 처음에는 거리가 0 -
순회 시작
큐에 값이 없을 때까지 반복 큐의 값을 꺼내서 키와 값을 추출하고
키가 결과맵에 없다면 추가하고 계속 진행
키에 연관된 값들을 가져와서 비용을 계산해준 후 큐에 더한다. (큐에 값이 없을 때까지 반복) -
검사
순회가 끝나면 결과 값에 쌓인 것이 n개인지 확인한다.(맞다면 모두 순회한 것)
같지 않다면 일부 노드에는 도달할 수 없음으로 판단한여 -1 반환
import java.util.*;
class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
// 1. 담기
Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
for(int[] time : times) {
map.putIfAbsent(time[0], new HashMap<>());
map.get(time[0]).put(time[1], time[2]);
}
// 2. 큐 준비 (도착지, 소요시간)
Queue<Map.Entry<Integer, Integer>> q = new PriorityQueue<>(Map.Entry.comparingByValue());
q.add(new AbstractMap.SimpleEntry<>(k, 0)); // 시작값 셋팅
// 결과 배열 준비
Map<Integer, Integer> result = new HashMap<>();
// 순회 시작
while(!q.isEmpty()) {
Map.Entry<Integer, Integer> temp = q.poll();
Integer dest = temp.getKey();
Integer cost = temp.getValue();
if(!result.containsKey(dest)) {
result.put(dest, cost);
if(map.containsKey(dest)) {
for(Map.Entry<Integer, Integer> t : map.get(dest).entrySet()) {
int alt = cost + t.getValue();
q.add(new AbstractMap.SimpleEntry<>(t.getKey(), alt));
}
}
}
}
// 검사
if(result.size() == n) {
// 가장 오래걸리는 지점의 소요시간 추출
return Collections.max(result.values());
}
// 일부 노드에는 도달할 수 없음
return -1;
}
}
참고 도서 : 자바 알고리즘 인터뷰 with 코틀린 469p