leetcodeNo743. Network Delay Time

Question

743. Network Delay Time

There are N network nodes, labelled 1 to N.

Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time it takes for a signal to travel from source to target.

Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1.

Example 1:

leetcodeNo743. Network Delay Time_第1张图片

Input: times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
Output: 2

Note:

  1. N will be in the range [1, 100].
  2. K will be in the range [1, N].
  3. The length of times will be in the range [1, 6000].
  4. All edges times[i] = (u, v, w) will have 1 <= u, v <= N and 0 <= w <= 100.

Algorithm

很显然,这一题用Dijkstra法解决,这个算法请参考《算法图解》第七章。这一题,我们要思考两个问题:

  • 需要用到哪些数据结构?
  • 如何用这些数据结构来实现Dijkstra算法?

需要用到哪些数据结构?

我们先来看看Dijkstra算法的步骤:(稍后来具体解释)

  1. 找到可在最短时间内到达的节点
  2. 更新该节点邻居的路径长度(记录到达每个节点路径长度的列表
  3. 重复,直到每个节点都执行过1和2(hash表记录已经执行过的节点
  4. 计算最短路径

由上面的分析,可以得出需要一个数组和一个hash表(可以用其他方式替代),加上表示图邻接表,我们一共需要三张表

  • 邻接表(vector>> graph
    • 这里用pair的形式是为了方便coding
  • 表示路径长度(vector dis
  • 记录已经执行过的节点(unordered_set hash

如何用这些数据结构来实现Dijkstra算法?

这里用一个简单的例子和图来说明吧,遍历完所有的节点,然后找到路径长度表中最长的路径长度即为题目中的网络延迟时间了。

leetcodeNo743. Network Delay Time_第2张图片
leetcodeNo743. Network Delay Time_第3张图片

Code

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int N, int K) {
        vector<vector<pair<int, int>> > graph(N+1);
        vector<int> dis(N+1, INT_MAX);
        unordered_set<int> hash;

        //create graph and init dis
        for (auto edge : times){
            graph[edge[0]].push_back(make_pair(edge[1], edge[2]));
        }
        dis[K] = 0;
		int cur = K;
        
        while (cur > 0){
            hash.insert(cur);
            int cur_dis = dis[cur];
            for (auto node : graph[cur]){
                int node_dis = cur_dis + node.second;
                if (node_dis < dis[node.first] && hash.find(node.first) == hash.end()){
                    dis[node.first] = node_dis;
                }
            }

            //find the next node
            int tmp = INT_MAX;
            cur = -1;
            for (int i=1; i<=N; i++){
                if (dis[i]<tmp && hash.find(i)==hash.end()){
                    tmp = dis[i];
                    cur = i;
                }
            }
        }

        int maxRes = 0;
        for (int i=1; i<=N; i++){
            maxRes = max(maxRes, dis[i]);
        }

        return maxRes == INT_MAX? -1 : maxRes;
    }
};

leetcodeNo743. Network Delay Time_第4张图片
上面的解法,时间复杂度一般,空间复杂度更是感人,看看有什么可以优化的地方。
找下一个节点时,每次都用一遍循环,这里我们每次只想找最小,所以可以用最小堆来优化这个地方。

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int N, int K) {
        vector<vector<pair<int, int>> > graph(N+1);
        vector<int> dis(N+1, INT_MAX);
        unordered_set<int> hash;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> node_heap;

        //create graph and init dis
        for (auto edge : times){
            graph[edge[0]].push_back(make_pair(edge[1], edge[2]));
        }
        dis[K] = 0;
        node_heap.emplace(0, K);
        
        while (!node_heap.empty()){
            int cur = node_heap.top().second;
            node_heap.pop();
            hash.insert(cur);
            int cur_dis = dis[cur];
            for (auto node : graph[cur]){
                int node_dis = cur_dis + node.second;
                if (node_dis < dis[node.first] && hash.find(node.first) == hash.end()){
                    dis[node.first] = node_dis;
                    node_heap.emplace(node_dis, node.first);
                }
            }

            //find the next node
            int tmp = INT_MAX;
            cur = -1;
            for (int i=1; i<=N; i++){
                if (dis[i]<tmp && hash.find(i)==hash.end()){
                    tmp = dis[i];
                    cur = i;
                }
            }
        }

        int maxRes = 0;
        for (int i=1; i<=N; i++){
            maxRes = max(maxRes, dis[i]);
        }

        return maxRes == INT_MAX? -1 : maxRes;
    }
};

leetcodeNo743. Network Delay Time_第5张图片
更多题解可以关注我的微信公众号Coder101
leetcodeNo743. Network Delay Time_第6张图片

你可能感兴趣的:(leetcode)