일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- BFS
- heap
- Bellman-Ford
- ArrayList vs LinkedList
- Hashtable
- dfs
- array
- python3
- 자료구조
- sorting
- Easy
- Two Pointers
- DailyLeetCoding
- hash
- Java
- SinglyLinkedList
- Union Find
- Leedcode
- LinkedList
- VCS
- stack
- 구현
- hash table
- String
- graph
- Medium
- A* Algorithm
- greedy
- 광연자동차운전면허학원
- leetcode
- Today
- Total
Min IT's Devlog
[python3] 1557. Minimum Number of Vertices to Reach All Nodes 본문
[python3] 1557. Minimum Number of Vertices to Reach All Nodes
egovici 2023. 5. 18. 09:59풀이 일자: 23.05.18
난이도: [Medium]
분류: [Graph]
문제 내용
문제의 내용은 0 ~ N-1까지의 노드가 있는 순환이 없는 graph가 주어졌을 때 모든 노드에 접근하는 것이 목표이다. 최소한의 시작점을 사용하여 위와 같은 목표를 달성할 때 그 때의 시작점들의 집합을 리턴하는 것이 목표이다.
문제 해결 흐름
1. 처음에는 Union-Find를 생각해보았지만 그래프가 방향성이 있는 그래프이고 모두 합쳐져 있어서 부적합하다.
→ Union-Find는 Pass
2. 그래프를 직접 순회해가면서 각 노드가 접근할 수 있는 노드들의 집합을 구하는 것이 어떨까?
→ 가능은 하지만 시간이 오래 걸릴 것이다. 이는 cycle이 존재할 수 있어 이에 대한 처리가 필요하고 각 시작점에서 접근가능한 노드가 겹칠 수 있어 비효율적으로 보인다.
3. Hint를 참조했을 때 income 노드의 여부를 확인하라는 idea가 있었다.
→ 생각해보니 매우 합리적인 idea였다. 화살표의 대상이 되는 노드의 경우 어쨌든 다른 노드를 통해서 접근이 가능하기 때문에 화살표의 대상이 되지 않는 노드 즉 다른 노드에서 접근하지 않는 노드만 count하면 되겠다.
class Solution:
def findSmallestSetOfVertices(self, n: int, edges: List[List[int]]) -> List[int]:
income = set();
for i in range(len(edges)):
income.add(edges[i][1]);
ans = list();
for i in range(n):
if i not in income:
ans.append(i);
return ans;
Time Complexity: O(N+E)
각각 edge와 node에 대해 순회를 돌리기 때문에 edge와 node의 최대값이 Time Complexity가 될 것이다.
Space Complexity: O(N)
화살표의 대상이 되는 노드를 income에 저장하고 그 이외의 값을 ans에 저장하기 때문에 공간복잡도는 N이 될 것이다.
다른 해결 방식
1. 내 풀이보다 좀 더 심플한 방법을 사용한다면(다른 사람 풀이)
→ set에서의 차집합 개념을 이용하여 단순하게 만들었다.
class Solution:
def findSmallestSetOfVertices(self, n, edges):
all_nodes = set(range(n))
destination_nodes = set(destination for _, destination in edges)
source_nodes = all_nodes - destination_nodes
return list(source_nodes)
2. BFS를 이용한 풀이도 존재하였다.(다른 사람 풀이)
→ 기존의 BFS 알고리즘을 이용하여 순회를 하는 방식이다.
from collections import defaultdict
class Solution(object):
def __init__(self):
self.graph = defaultdict(list)
self.visited = list()
self.res = set()
def findSmallestSetOfVertices(self, n, edges):
self.visited = [False for i in range(n)]
for u, v in edges:
self.graph[u].append(v)
for i in range(n):
if not self.visited[i]:
self.dfs(i)
self.res.add(i) # 현재 노드를 시작점으로 추가
return list(self.res)
def dfs(self, idx):
self.visited[idx] = True
for adj in self.graph[idx]:
if not self.visited[adj]: # 방문한 적이 없다면 해당 노드에서 dfs 시작
self.dfs(adj)
elif adj in self.res: # 앞으로 방문해야 하는 node가 시작점에 포함되어 있다면 삭제
self.res.remove(adj)
문제 링크
https://leetcode.com/problems/minimum-number-of-vertices-to-reach-all-nodes/description/
Minimum Number of Vertices to Reach All Nodes - LeetCode
Can you solve this real interview question? Minimum Number of Vertices to Reach All Nodes - Given a directed acyclic graph, with n vertices numbered from 0 to n-1, and an array edges where edges[i] = [fromi, toi] represents a directed edge from
leetcode.com
'코테 > LeetCode(Solve)' 카테고리의 다른 글
[python3] 347. Top K Frequent Elements (1) | 2023.05.22 |
---|---|
[python3] 785. Is Graph Bipartite? (1) | 2023.05.19 |
[python3] 2130. Maximum Twin Sum of a Linked List (1) | 2023.05.17 |
[python3] 24. Swap Nodes in Pairs (1) | 2023.05.16 |
[python3] 516. Longest Palindromic Subsequence (0) | 2023.04.14 |