문제 출처 :
https://school.programmers.co.kr/learn/courses/30/lessons/49189
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 설명 :
n개의 노드가 있는 그래프가 있습니다. 각 노드는 1부터 n까지 번호가 적혀있습니다. 1번 노드에서 가장 멀리 떨어진 노드의 갯수를 구하려고 합니다. 가장 멀리 떨어진 노드란 최단경로로 이동했을 때 간선의 개수가 가장 많은 노드들을 의미합니다.
노드의 개수 n, 간선에 대한 정보가 담긴 2차원 배열 vertex가 매개변수로 주어질 때, 1번 노드로부터 가장 멀리 떨어진 노드가 몇 개인지를 return 하도록 solution 함수를 작성해주세요.
제한사항
- 노드의 개수 n은 2 이상 20,000 이하입니다.
- 간선은 양방향이며 총 1개 이상 50,000개 이하의 간선이 있습니다.
- vertex 배열 각 행 [a, b]는 a번 노드와 b번 노드 사이에 간선이 있다는 의미입니다.
입출력 예
n vertex return
6 | [[3, 6], [4, 3], [3, 2], [1, 3], [1, 2], [2, 4], [5, 2]] | 3 |
입출력 예 설명
예제의 그래프를 표현하면 아래 그림과 같고, 1번 노드에서 가장 멀리 떨어진 노드는 4,5,6번 노드입니다.
문제 풀이 :
그래프 문제를 구현할 때 인접행렬을 이용하거나 인접리스트를 이용하는 방법이 있다.
인접행렬은 주로 밀집 그래프 ( E ≈ N² 간선의 개수가 노드의 개수의 제곱의 수와 비슷하다)인 경우에 사용한다.
-> 간선이 존재하는 배열을 1로 모두 채울 수 있기 때문에 공간을 낭비하지 않고 효율적으로 사용할 수 있다.
인접리스트는 간선이 적은 희소 그래프일 때 더 유리하다. ( E << N² )
✅ 인접 행렬 vs 인접 리스트 비교
인접 행렬 (Adjacency Matrix) 인접 리스트 (Adjacency List)
공간 복잡도 | O(N²) (노드 개수의 제곱) | O(N + E) (노드 + 간선 개수) |
간선 개수 많을 때(밀집 그래프) | ✅ 간선이 많으면 효율적 (공간 낭비 적음) | ❌ 노드 개수에 비해 메모리 낭비 발생 |
간선 개수 적을 때(희소 그래프) | ❌ 메모리 낭비 큼 (많은 0이 존재) | ✅ 간선이 적을수록 메모리 절약 가능 |
간선 여부 확인 (O(1)) | ✅ 배열 접근만으로 즉시 확인 가능 | ❌ 리스트 탐색 필요 (O(N)) |
모든 이웃 탐색 (O(N)) | ❌ 전체 배열을 확인해야 함 | ✅ 연결된 노드만 탐색 가능 (O(E)) |
제한 사항으로 봤을 때 인접리스트를 활용하여 문제를 푸는 것이 효율적이라고 생각되어 인접리스트로 문제를 풀게 되었다.
이 문제의 포인트
1. 2차원배열의 edges를 인접리스트 형태로 담아 서로 연결시킨 그래프로 만든다.
2. 현재노드에서 최단거리로 연결된 노드를 찾고, 이 때 방문 여부와 연결 횟수 정보를 확인할 Distance배열을 사용한다.
BFS를 통해 더 이상 연결된 노드가 없을 때까지 반복한다.
3. 가장 큰 Distance 값을 찾고, 이와 동일한 개수를 가진 Node의 개수를 반환한다.
import java.util.*;
class Solution {
public int solution(int n, int[][] edge) {
int answer = 0;
ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>();
int[] dist = new int[n+1];
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<Integer>());
}
// 간선 연결
for (int[] e : edge) {
graph.get(e[0]).add(e[1]);
graph.get(e[1]).add(e[0]);
}
//최단거리 찾기
Arrays.fill(dist, -1);
Queue<Integer> q = new LinkedList<>();
q.add(1);
dist[1] = 0;
while (!q.isEmpty()) {
int curNode = q.poll();
ArrayList<Integer> nodeList = graph.get(curNode);
for (int i = 0; i < nodeList.size(); i++) {
int nxNode = nodeList.get(i);
if (dist[nxNode] == -1) { // 방문하지 않은 노드 체크
dist[nxNode] = dist[curNode] + 1;
q.add(nxNode);
}
}
}
int max = Arrays.stream(dist).max().getAsInt();
//System.out.println("max: " + max);
for (int i = 0; i < dist.length; i++) {
if (dist[i] == max) {
answer++;
}
}
return answer;
}
}
dist[nxNode] = dist[curNode] + 1;
현재노드에 연결된 노드(nxNode)의 연결 횟수 값은 이전의 값에 1을 더한 값과 같다.
'알고리즘 > 프로그래머스 문제풀이' 카테고리의 다른 글
프로그래머스(lv3) - 순위 / 그래프(java) (0) | 2025.03.21 |
---|---|
프로그래머스(lv 3) - 단어 변환 (Java/자바) DFS/BFS (1) | 2024.10.24 |
프로그래머스 LV1 > 체육복 (자바/JAVA) - 그리디 알고리즘 (0) | 2024.10.18 |
프로그래머스 lv3 > 네트워크 (DFS) (JAVA/자바) (1) | 2024.10.16 |
프로그래머스 lv2 > 게임 맵 최단거리 (0) | 2024.10.16 |