leetcode
leetcode 1451 ~ 1500
最大网络秩

最大网络秩

难度:

标签:

题目描述

n 座城市和一些连接这些城市的道路 roads 共同组成一个基础设施网络。每个 roads[i] = [ai, bi] 都表示在城市 aibi 之间有一条双向道路。

两座不同城市构成的 城市对网络秩 定义为:与这两座城市 直接 相连的道路总数。如果存在一条道路直接连接这两座城市,则这条道路只计算 一次

整个基础设施网络的 最大网络秩 是所有不同城市对中的 最大网络秩

给你整数 n 和数组 roads,返回整个基础设施网络的 最大网络秩

 

示例 1:

输入:n = 4, roads = [[0,1],[0,3],[1,2],[1,3]]
输出:4
解释:城市 0 和 1 的网络秩是 4,因为共有 4 条道路与城市 0 或 1 相连。位于 0 和 1 之间的道路只计算一次。

示例 2:

输入:n = 5, roads = [[0,1],[0,3],[1,2],[1,3],[2,3],[2,4]]
输出:5
解释:共有 5 条道路与城市 1 或 2 相连。

示例 3:

输入:n = 8, roads = [[0,1],[1,2],[2,3],[2,4],[5,6],[5,7]]
输出:5
解释:2 和 5 的网络秩为 5,注意并非所有的城市都需要连接起来。

 

提示:

  • 2 <= n <= 100
  • 0 <= roads.length <= n * (n - 1) / 2
  • roads[i].length == 2
  • 0 <= ai, bi <= n-1
  • ai != bi
  • 每对城市之间 最多只有一条 道路相连

代码结果

运行时间: 43 ms, 内存: 17.5 MB


/*
题目思路:
1. 使用数组和流操作来统计每个城市的道路数目。
2. 使用二维布尔数组记录城市之间是否直接相连。
3. 通过流操作计算所有城市对的网络秩,并找到最大值。
*/

import java.util.Arrays;

public class Solution {
    public int maximalNetworkRank(int n, int[][] roads) {
        int[] roadCount = new int[n];
        boolean[][] isConnected = new boolean[n][n];

        Arrays.stream(roads).forEach(road -> {
            int a = road[0];
            int b = road[1];
            roadCount[a]++;
            roadCount[b]++;
            isConnected[a][b] = true;
            isConnected[b][a] = true;
        });

        return Arrays.stream(roadCount)
                .boxed()
                .flatMap(i -> Arrays.stream(roadCount)
                        .boxed()
                        .map(j -> new int[]{i, j}))
                .filter(pair -> pair[0] != pair[1])
                .mapToInt(pair -> {
                    int rank = roadCount[pair[0]] + roadCount[pair[1]];
                    if (isConnected[pair[0]][pair[1]]) rank--;
                    return rank;
                })
                .max()
                .orElse(0);
    }
}

解释

方法:

此题解通过计算每座城市连接的道路数量并使用两个数组来追踪每个城市的道路数(cnt数组)以及是否有直接连接两座城市的道路(point矩阵)。首先,它记录了所有城市的道路数量,并识别出连接最多道路的城市('first')和次多的城市('second')。如果最多道路的城市有超过一个,则检查这些城市之间是否有直接连接的道路。如果没有直接连接,则它们的网络秩是两倍的'first'值。如果有直接连接的城市,则减去一,因为这条路被重复计算了一次。如果最大道路数的城市只有一个,那么需要检查与次大道路数城市之间的直接连接情况,并相应调整计算结果。

时间复杂度:

O(n^2)

空间复杂度:

O(n^2)

代码细节讲解

🦆
在题解中提到使用`cnt数组`和`point矩阵`来追踪城市的道路数和直接连接情况,请问这种数据结构的选择对算法的效率有什么影响?
使用`cnt数组`和`point矩阵`这两种数据结构提高了算法的效率。`cnt数组`通过索引直接存储每个城市的道路数量,使得更新和查询道路数都是O(1)的时间复杂度。`point矩阵`作为二维布尔数组,直接记录任意两个城市之间是否存在直接连接,这使得查询两城市间的连接状态也是O(1)时间复杂度。整体上,这种数据结构的选择使得算法在处理连接查询和更新时非常高效,尤其是在频繁查询和少量更新的情况下,能够快速响应。
🦆
题解中提到如果`最多道路的城市有超过一个`,则需要检查这些城市之间是否有直接连接的道路。请问为什么要特别检查这些城市之间的直接连接情况?
当有多个城市拥有相同的最高道路数时,这些城市之间的直接连接情况会直接影响网络秩的计算。如果这些城市之间没有直接连接,那么选择这两个城市作为网络的一部分将不会重复计算任何道路,因此网络秩是两者道路数的简单相加。然而,如果这些城市之间有直接连接的道路,选择这两个城市会导致这条道路被重复计算,因此需要从总和中减去这条重复的道路。这是为了确保网络秩的计算准确无误,避免重复计数。
🦆
当最多道路的城市只有一个时,算法需要检查与次大道路数城市之间的直接连接情况。这种情况下,为什么结果是`first + second - all(point[i][j] for j in sarr)`,特别是`all`函数在这里是如何应用的?
在这种情况下,算法需要确定最大道路数的城市和次大道路数的城市之间是否存在直接连接。`all`函数在这里用于检查是否所有次大道路数城市与最大道路数城市之间都有直接连接。如果`all(point[i][j] for j in sarr)`返回`True`,这意味着每个次大道路数城市都与最大道路数的城市有直接连接,因此需要从总和`first + second`中减去1,避免重复计数道路。如果返回`False`,则表示至少有一个次大道路数城市与最大道路数城市没有直接连接,此时网络秩应为`first + second`。

相关问题