|
| 1 | +class Solution { |
| 2 | + private int dfs(int node, String colors, Map<Integer, List<Integer>> adj, int[][] count, |
| 3 | + boolean[] visit, boolean[] inStack) { |
| 4 | + // If the node is already in the stack, we have a cycle. |
| 5 | + if (inStack[node]) { |
| 6 | + return Integer.MAX_VALUE; |
| 7 | + } |
| 8 | + if (visit[node]) { |
| 9 | + return count[node][colors.charAt(node) - 'a']; |
| 10 | + } |
| 11 | + // Mark the current node as visited and part of current recursion stack. |
| 12 | + visit[node] = true; |
| 13 | + inStack[node] = true; |
| 14 | + |
| 15 | + if (adj.containsKey(node)) { |
| 16 | + for (int neighbor : adj.get(node)) { |
| 17 | + if (dfs(neighbor, colors, adj, count, visit, inStack) == Integer.MAX_VALUE) { |
| 18 | + return Integer.MAX_VALUE; |
| 19 | + } |
| 20 | + for (int i = 0; i < 26; i++) { |
| 21 | + count[node][i] = Math.max(count[node][i], count[neighbor][i]); |
| 22 | + } |
| 23 | + } |
| 24 | + } |
| 25 | + |
| 26 | + // After all the incoming edges to the node are processed, |
| 27 | + // we count the color on the node itself. |
| 28 | + count[node][colors.charAt(node) - 'a']++; |
| 29 | + // Remove the node from the stack. |
| 30 | + inStack[node] = false; |
| 31 | + return count[node][colors.charAt(node) - 'a']; |
| 32 | + } |
| 33 | + |
| 34 | + public int largestPathValue(String colors, int[][] edges) { |
| 35 | + int n = colors.length(); |
| 36 | + Map<Integer, List<Integer>> adj = new HashMap<>(); |
| 37 | + |
| 38 | + for (int[] edge : edges) { |
| 39 | + adj.computeIfAbsent(edge[0], k->new ArrayList<Integer>()).add(edge[1]); |
| 40 | + } |
| 41 | + |
| 42 | + int[][] count = new int[n][26]; |
| 43 | + boolean[] visit = new boolean[n]; |
| 44 | + boolean[] inStack = new boolean[n]; |
| 45 | + int answer = 0; |
| 46 | + for (int i = 0; i < n; i++) { |
| 47 | + answer = Math.max(answer, dfs(i, colors, adj, count, visit, inStack)); |
| 48 | + } |
| 49 | + |
| 50 | + return answer == Integer.MAX_VALUE ? -1 : answer; |
| 51 | + } |
| 52 | +} |
0 commit comments