LeetCode——1857. 有向图中最大颜色值(Largest Color Value in a Directed Graph)[困难]——分析及代码(Java)

LeetCode——1857. 有向图中最大颜色值[Largest Color Value in a Directed Graph][困难]——分析及代码[Java]

  • 一、题目
  • 二、分析及代码
    • 1. 拓扑排序 + 动态规划
      • (1)思路
      • (2)代码
      • (3)结果
  • 三、其他

一、题目

给你一个 有向图 ,它含有 n 个节点和 m 条边。节点编号从 0 到 n - 1 。

给你一个字符串 colors ,其中 colors[i] 是小写英文字母,表示图中第 i 个节点的 颜色 (下标从 0 开始)。同时给你一个二维数组 edges ,其中 edges[j] = [aj, bj] 表示从节点 aj 到节点 bj 有一条 有向边 。

图中一条有效 路径 是一个点序列 x1 -> x2 -> x3 -> … -> xk ,对于所有 1 <= i < k ,从 xi 到 xi+1 在图中有一条有向边。路径的 颜色值 是路径中 出现次数最多 颜色的节点数目。

请你返回给定图中有效路径里面的 最大颜色值 。如果图中含有环,请返回 -1 。

示例 1:

输入:colors = "abaca", edges = [[0,1],[0,2],[2,3],[3,4]]
输出:3
解释:路径 0 -> 2 -> 3 -> 4 含有 3 个颜色为 "a" 的节点。

示例 2:

输入:colors = "a", edges = [[0,0]]
输出:-1
解释:从 0 到 0 有一个环。

提示:

  • n == colors.length
  • m == edges.length
  • 1 <= n <= 10^5
  • 0 <= m <= 10^5
  • colors 只含有小写英文字母。
  • 0 <= aj, bj < n

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-color-value-in-a-directed-graph
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、分析及代码

1. 拓扑排序 + 动态规划

(1)思路

对各节点进行拓扑排序,判断有向图中是否存在环,并得到节点的拓扑序列,在此基础上结合动态规划方法反向求解。

(2)代码

class Solution {
    public int largestPathValue(String colors, int[][] edges) {
        int n = colors.length();
        int[] deg = new int[n];//各节点入度
        Arrays.fill(deg, 0);
        List<List<Integer>> list = new ArrayList<List<Integer>>(n);//邻接表
        for (int i = 0; i < n; i++)
            list.add(new ArrayList<Integer>());
        
        //入度和邻接表初始化
        for (int[] edge : edges) {
            int u = edge[0], v = edge[1];
            deg[v]++;
            list.get(u).add(v);
        }

        //拓扑排序
        int[] topo = new int[n];
        int nodeNum = 0;//当前已拓扑排序的节点数
        Queue<Integer> q = new LinkedList<>();//暂存当前入度为0的节点
        for (int i = 0; i < n; i++)
            if (deg[i] == 0)
                q.offer(i);
        while (!q.isEmpty()) {
            int u = q.poll();
            topo[nodeNum++] = u;
            for (Integer v : list.get(u)) {
                if (--deg[v] == 0)
                    q.offer(v);
            }
        }
        if (nodeNum < n)//图中有环
            return -1;
        
        int ans = 0;
        for (int i = 0; i < 26; i++) {//依次遍历26种颜色
            char color =(char)((int)'a' + i);//当前颜色
            int[] dp = new int[n];//动态规划结果
            Arrays.fill(dp, 0);
            for (int j = n - 1; j >= 0; j--) {//按照拓扑顺序从后向前动态规划
                int u = topo[j];
                for (Integer v : list.get(u))
                    dp[u] = Math.max(dp[u], dp[v]);//后续路径中当前颜色的最大节点个数
                if (colors.charAt(u) == color)
                    dp[u]++;
                ans = Math.max(ans, dp[u]);
            }
        }
        return ans;
    }
}

(3)结果

执行用时 :285 ms,在所有 Java 提交中击败了 19.76% 的用户;
内存消耗 :98 MB,在所有 Java 提交中击败了 70.97% 的用户。

三、其他

暂无。

你可能感兴趣的:(数据结构与算法,LeetCode,Java,题解)