Floyd-Warshall 解題模板,助你快速AC

Floyd-Warshall 是解決任意兩點間的最短路徑的一種算法,LeetCode 有不少題目都用了,掌握這套解題模板幫你快速 AC。python

題目地址(1334. 閾值距離內鄰居最少的城市)

https://leetcode-cn.com/probl...算法

題目描述

有 n 個城市,按從 0 到 n-1 編號。給你一個邊數組 edges,其中 edges[i] = [fromi, toi, weighti] 表明 fromi 和 toi 兩個城市之間的雙向加權邊,距離閾值是一個整數 distanceThreshold。

返回能經過某些路徑到達其餘城市數目最少、且路徑距離 最大 爲 distanceThreshold 的城市。若是有多個這樣的城市,則返回編號最大的城市。

注意,鏈接城市 i 和 j 的路徑的距離等於沿該路徑的全部邊的權重之和。

 

示例 1:

image.png

輸入:n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
輸出:3
解釋:城市分佈圖如上。
每一個城市閾值距離 distanceThreshold = 4 內的鄰居城市分別是:
城市 0 -> [城市 1, 城市 2] 
城市 1 -> [城市 0, 城市 2, 城市 3] 
城市 2 -> [城市 0, 城市 1, 城市 3] 
城市 3 -> [城市 1, 城市 2] 
城市 0 和 3 在閾值距離 4 之內都有 2 個鄰居城市,可是咱們必須返回城市 3,由於它的編號最大。
示例 2:

image.png

輸入:n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
輸出:0
解釋:城市分佈圖如上。 
每一個城市閾值距離 distanceThreshold = 2 內的鄰居城市分別是:
城市 0 -> [城市 1] 
城市 1 -> [城市 0, 城市 4] 
城市 2 -> [城市 3, 城市 4] 
城市 3 -> [城市 2, 城市 4]
城市 4 -> [城市 1, 城市 2, 城市 3] 
城市 0 在閾值距離 4 之內只有 1 個鄰居城市。
 

提示:

2 <= n <= 100
1 <= edges.length <= n * (n - 1) / 2
edges[i].length == 3
0 <= fromi < toi < n
1 <= weighti, distanceThreshold <= 10^4
全部 (fromi, toi) 都是不一樣的。

思路

這道題的本質就是:segmentfault

  1. 在一個無向圖中尋找每兩個城鎮的最小距離,咱們使用 Floyd-Warshall 算法(英語:Floyd-Warshall algorithm),中文亦稱弗洛伊德算法,是解決任意兩點間的最短路徑的一種算法。
  2. 篩選最小距離不大於  distanceThreshold 的城鎮。
  3. 統計每一個城鎮,其知足條件的城鎮有多少個
  4. 咱們找出最少的便可

Floyd-Warshall 算法的時間複雜度和空間複雜度都是$O(N^3)$, 而空間複雜度能夠優化到$O(N^2)$。Floyd-Warshall 的基本思想是對於每兩個點之間的最小距離,要麼通過中間節點 k,要麼不通過,咱們取二者的最小值,這是一種動態規劃思想,詳細的解法能夠參考Floyd-Warshall 算法(wikipedia)數組

代碼

代碼支持:Python3優化

Python3 Code:spa

class Solution:
    def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
        # 構建dist矩陣
        dist = [[float('inf')] * n for _ in  range(n)]
        for i, j, w in edges:
            dist[i][j] = w
            dist[j][i] = w
        for i in range(n):
            dist[i][i] = 0
        for k in range(n):
            for i in range(n):
                for j in range(n):
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])

        # 過濾
        res = 0
        minCnt = float('inf')
        for i in range(n):
            cnt = 0
            for d in dist[i]:
                if d <= distanceThreshold:
                    cnt += 1
            if cnt <= minCnt:
                minCnt = cnt
                res = i
        return res

關鍵點解析

  • Floyd-Warshall 算法
  • 你能夠將本文給的 Floyd-Warshall 算法當成一種解題模板使用
相關文章
相關標籤/搜索