프로그래머스 3단계 : 부대복귀 (Java 자바)

2023. 9. 7. 03:33·💻 코딩테스트/programmers
728x90

문제 설명
강철부대의 각 부대원이 여러 지역에 뿔뿔이 흩어져 특수 임무를 수행 중입니다. 지도에서 강철부대가 위치한 지역을 포함한 각 지역은 유일한 번호로 구분되며, 두 지역 간의 길을 통과하는 데 걸리는 시간은 모두 1로 동일합니다. 임무를 수행한 각 부대원은 지도 정보를 이용하여 최단시간에 부대로 복귀하고자 합니다. 다만 적군의 방해로 인해, 임무의 시작 때와 다르게 되돌아오는 경로가 없어져 복귀가 불가능한 부대원도 있을 수 있습니다.

강철부대가 위치한 지역을 포함한 총지역의 수 n, 두 지역을 왕복할 수 있는 길 정보를 담은 2차원 정수 배열 roads, 각 부대원이 위치한 서로 다른 지역들을 나타내는 정수 배열 sources, 강철부대의 지역 destination이 주어졌을 때, 주어진 sources의 원소 순서대로 강철부대로 복귀할 수 있는 최단시간을 담은 배열을 return하는 solution 함수를 완성해주세요. 복귀가 불가능한 경우 해당 부대원의 최단시간은 -1입니다.

 


제한사항

  • 3 ≤ n ≤ 100,000
    • 각 지역은 정수 1부터 n까지의 번호로 구분됩니다.
  • 2 ≤ roads의 길이 ≤ 500,000
    • roads의 원소의 길이 = 2
    • roads의 원소는 [a, b] 형태로 두 지역 a, b가 서로 왕복할 수 있음을 의미합니다.(1 ≤ a, b ≤ n, a ≠ b)
    • 동일한 정보가 중복해서 주어지지 않습니다.
      • 동일한 [a, b]가 중복해서 주어지지 않습니다.
      • [a, b]가 있다면 [b, a]는 주어지지 않습니다.
  • 1 ≤ sources의 길이 ≤ 500
    • 1 ≤ sources[i] ≤ n
  • 1 ≤ destination ≤ n

 

입출력 예

 

풀이

강철부대의 부대원들이 여러 지역에서 특수 임무를 수행하고, 각 부대원이 최단 시간에 부대로 복귀할 수 있는지를 계산하는 문제입니다. 지도에서의 지역은 번호로 구분되며, 지역 간 이동에는 1의 시간이 소요됩니다. 다만, 복귀 경로가 존재하지 않을 수도 있습니다. 이때, 부대원들의 복귀 가능 여부와 최단 시간을 반환해야 합니다.

 

그래프 생성: 주어진 지역 간 길 정보를 바탕으로 양방향 그래프를 생성합니다. 이 그래프는 map에 저장되며, 각 지역과 이에 연결된 지역들의 목록을 포함합니다.
=> Map<integer, list> map = new HashMap<>();: 그래프를 표현하기 위한 HashMap을 초기화합니다. 이 맵은 지역 번호를 키로 가지며 해당 지역과 연결된 지역 목록을 값으로 갖습니다.

 

< 다익스트라 알고리즘 시작 >
다익스트라 알고리즘: 복귀 가능한 경로를 찾기 위해 다익스트라 알고리즘을 사용합니다. 시작 지점은 destination으로 고정되며, 모든 지역까지의 최단 시간을 계산합니다.

 

boolean[] visited = new boolean[n + 1];: 방문 여부를 나타내는 배열을 초기화합니다. 인덱스 0은 사용하지 않으므로 n + 1로 초기화합니다.

 

int[] dp = new int[n + 1];: 최단 시간을 저장할 배열을 초기화합니다. 초기 값으로는 최댓값 Integer.MAX_VALUE로 설정합니다.


큐 que를 사용하여 BFS를 구현합니다. destination을 큐에 추가하고, 해당 지역부터 출발하여 모든 지역까지의 최단 경로를 계산합니다. 각 지역에 대해 연결된 지역을 확인하고, 아직 방문하지 않은 지역이라면 방문 체크를 하고 최단 경로를 업데이트합니다.

복귀 가능 여부 및 최단 시간 계산: 주어진 sources 배열의 각 부대원에 대해, 해당 지역으로의 최단 시간을 계산하고, 복귀 경로가 없는 경우 -1로 설정합니다.

결과 배열 생성: 모든 부대원에 대한 최단 시간을 계산하고, 이를 result 리스트에 저장합니다.

결과 반환: result 리스트를 배열로 변환하여 최종적인 결과를 반환합니다.

 

for (int[] road : roads) { ... }: roads 배열을 순회하면서 양방향 길을 설정하여 그래프를 만듭니다.

List<Integer> result = new ArrayList<>();: 각 부대원의 복귀 가능 여부와 최단 시간을 저장할 리스트를 초기화합니다.

for (int s : sources) { ... }: sources 배열에 있는 각 부대원에 대해 최단 시간을 계산하고, 복귀 경로가 없는 경우 -1로 설정합니다.

 

import java.util.*;

class Solution {
    public int[] solution(int n, int[][] roads, int[] sources, int destination) {
        int[] answer = {};

        // 그래프를 표현하기 위한 Map 초기화
        Map<Integer, List<Integer>> map = new HashMap<>();

        // roads 배열을 이용하여 그래프 생성
        for (int[] road : roads) {
            int a = road[0];
            int b = road[1];

            // 양방향의 길을 설정합니다.
            List<Integer> a_list = map.getOrDefault(a, new ArrayList<>());
            a_list.add(b);
            map.put(a, a_list);

            List<Integer> b_list = map.getOrDefault(b, new ArrayList<>());
            b_list.add(a);
            map.put(b, b_list);
        }

        // 다익스트라 알고리즘을 사용하여 최단 경로 계산
        boolean[] visited = new boolean[n + 1];
        int[] dp = new int[n + 1];
        
        // dp 배열을 초기화합니다. 최대값으로 설정하여 나중에 비교할 수 있도록 합니다.
        Arrays.fill(dp, Integer.MAX_VALUE);

        // 시작 지점(destination)을 큐에 추가합니다.
        Queue<Integer> que = new LinkedList<>();
        visited[destination] = true;
        que.add(destination);

        dp[destination] = 0;

        while (!que.isEmpty()) {
            int p = que.poll();

            // 현재 지역과 연결된 지역 목록을 가져옵니다.
            List<Integer> p_list = map.get(p);

            // 현재 지역과 연결된 모든 지역들을 순회합니다.
            for (int temp : p_list) {
                // 아직 방문하지 않은 지역이라면
                if (!visited[temp]) {
                    // 방문 체크를 하고, 최단 경로를 업데이트합니다.
                    visited[temp] = true;
                    dp[temp] = dp[p] + 1; // 현재 지역에서 다음 지역으로 이동하는 데 걸리는 시간은 1이므로 1을 더합니다.
                    que.add(temp);
                }
            }
        }

        // 각 부대원의 복귀 가능 여부와 최단 시간을 계산합니다.
        List<Integer> result = new ArrayList<>();
        for (int s : sources) {
            if (dp[s] == Integer.MAX_VALUE) {
                // 복귀 경로가 없는 경우 -1로 설정합니다.
                dp[s] = -1;
            }
            result.add(dp[s]);
        }

        // 결과를 배열로 변환합니다.
        answer = result.stream().mapToInt(i -> i).toArray();

        return answer;
    }
}
728x90
저작자표시 비영리 변경금지 (새창열림)

'💻 코딩테스트 > programmers' 카테고리의 다른 글

프로그래머스 3단계 : 풍선 터뜨리기 (Java 자바)  (0) 2023.09.12
프로그래머스 3단계 : 디스크 컨트롤러 (Java 자바)  (0) 2023.09.12
프로그래머스 3단계 : 연속 펄스 부분 수열의 합 (Java 자바)  (0) 2023.09.07
프로그래머스 3단계 : 가장 긴 팰린드롬 (Java 자바)  (0) 2023.09.07
프로그래머스 3단계 : 입국심사 (Java 자바)  (0) 2023.09.06
'💻 코딩테스트/programmers' 카테고리의 다른 글
  • 프로그래머스 3단계 : 풍선 터뜨리기 (Java 자바)
  • 프로그래머스 3단계 : 디스크 컨트롤러 (Java 자바)
  • 프로그래머스 3단계 : 연속 펄스 부분 수열의 합 (Java 자바)
  • 프로그래머스 3단계 : 가장 긴 팰린드롬 (Java 자바)
gxxg
gxxg
함께 일하고 싶은 개발자를 꿈꾸는 예비개발자의 공부 기록
  • gxxg
    공공
    gxxg
  • 전체
    오늘
    어제
    • 분류 전체보기 (138)
      • ☁️ 구름 x 카카오 Deep Dive 풀스택 (7)
        • html, css (1)
        • Java (3)
        • 스프링 MVC (0)
      • 💻 코딩테스트 (89)
        • 백준 (2)
        • programmers (87)
      • SQLD (1)
      • Language (3)
        • Java (2)
        • JavaScript (1)
      • Style Sheet (0)
        • CSS (0)
        • SCSS & SASS (0)
      • DBMS (2)
        • Oracle (2)
        • MySQL (0)
        • postgresql (0)
        • 데이터베이스 기초 이론 (0)
      • React (0)
      • SpringBoot (0)
      • JSP (2)
      • 알고리즘 (0)
      • 2023-02 몰입형 SW 정규 교육 (24)
        • 9월 프로젝트 (8)
      • 벽돌깨기 (4)
      • Etc (4)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JSP
    티스토리챌린지
    junit 테스트
    HTML
    코테
    CSS
    Lv2
    POST
    오블완
    코딩테스트
    프로젝트 구조
    springboot
    eclipse
    자바스크립트
    3단계
    LV3
    회원 관리 시스템
    Lv0
    이클립스
    구현체
    spring
    자바
    javascript
    0단계
    java
    DFS
    2단계
    programmers
    프로그래머스
    톰캣
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gxxg
프로그래머스 3단계 : 부대복귀 (Java 자바)
상단으로

티스토리툴바