The problem asks for the maximum count of any single color along any valid path in the graph. A direct approach is to try every possible starting node and every possible color, then use DFS to explore all paths and count how many nodes of that color we encounter. If we detect a cycle during DFS, the answer is -1 since valid paths cannot contain cycles.
0 to n-1, and for each color from 0 to 25:-1 immediately.class Solution:
def largestPathValue(self, colors: str, edges: list[list[int]]) -> int:
n = len(colors)
adj = [[] for _ in range(n)]
for u, v in edges:
adj[u].append(v)
visit = [False] * n
def dfs(node, c):
if visit[node]:
return float("inf")
visit[node] = True
clrCnt = 0
for nei in adj[node]:
cur = dfs(nei, c)
if cur == float("inf"):
return cur
clrCnt = max(clrCnt, cur)
visit[node] = False
return clrCnt + (c == (ord(colors[node]) - ord('a')))
res = -1
for i in range(n):
for c in range(26):
cnt = dfs(i, c)
if cnt == float("inf"):
return -1
res = max(res, cnt)
return resWhere is the number of verticies and is the number of edges.
Instead of checking one color at a time, we can track all 26 color counts simultaneously for each node. Using memoization, once we compute the maximum color counts reachable from a node, we store and reuse that result. We use two sets: one for globally visited nodes (already fully processed) and one for the current DFS path (to detect cycles).
count[node][color] to store the maximum count of each color reachable from each node.0.1.count[node][color], or -1 if a cycle was detected.class Solution:
def largestPathValue(self, colors: str, edges: list[list[int]]) -> int:
adj = defaultdict(list)
for src, dst in edges:
adj[src].append(dst)
def dfs(node):
if node in path:
return float("inf")
if node in visit:
return 0
visit.add(node)
path.add(node)
colorIndex = ord(colors[node]) - ord('a')
count[node][colorIndex] = 1
for nei in adj[node]:
if dfs(nei) == float("inf"):
return float("inf")
for c in range(26):
count[node][c] = max(
count[node][c],
(1 if c == colorIndex else 0) + count[nei][c]
)
path.remove(node)
return 0
n, res = len(colors), 0
visit, path = set(), set()
count = [[0] * 26 for _ in range(n)]
for i in range(n):
if dfs(i) == float("inf"):
return -1
res = max(res, max(count[i]))
return resWhere is the number of verticies and is the number of edges.
Since we need valid paths in a directed graph, topological sorting naturally fits. We process nodes in topological order using Kahn's algorithm (BFS with indegree tracking). For each node, we propagate color counts to its neighbors before they are processed. If we cannot process all nodes, a cycle exists. This approach avoids recursion and handles cycle detection elegantly.
count[node][color] for tracking color frequencies.0 to a queue.0, add it to the queue.n, return the result. Otherwise, return -1 (cycle detected).class Solution:
def largestPathValue(self, colors: str, edges: list[list[int]]) -> int:
n = len(colors)
adj = [[] for _ in range(n)]
indegree = [0] * n
count = [[0] * 26 for _ in range(n)]
for u, v in edges:
adj[u].append(v)
indegree[v] += 1
q = deque()
for i in range(n):
if indegree[i] == 0:
q.append(i)
visit = res = 0
while q:
node = q.popleft()
visit += 1
colorIndex = ord(colors[node]) - ord('a')
count[node][colorIndex] += 1
res = max(res, count[node][colorIndex])
for nei in adj[node]:
for c in range(26):
count[nei][c] = max(count[nei][c], count[node][c])
indegree[nei] -= 1
if indegree[nei] == 0:
q.append(nei)
return res if visit == n else -1Where is the number of verticies and is the number of edges.