LeetCode 317 題的詳細題目信息如下:
題目名稱
Shortest Distance from All Buildings(中文譯名:離建筑物最近的距離)
題目描述
給你一個由 0、1 和 2 組成的二維網格,其中:
- 0 代表空地
- 1 代表建筑物
- 2 代表障礙物
你需要找到一個空地,使其到所有建筑物的總曼哈頓距離之和最小。如果不存在這樣的空地(即沒有任何空地能到達所有建筑物),則返回 -1。
曼哈頓距離的計算方式為:對于兩個點 (x1, y1) 和 (x2, y2),其距離為 |x1 - x2| + |y1 - y2|。
示例
輸入:
[[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]
]
輸出:7
解釋:
網格中共有 3 個建筑物。位于 (1,2) 的空地到所有建筑物的總距離為 7(到 (0,0) 的距離為 3,到 (0,4) 的距離為 3,到 (2,2) 的距離為 1,總和 3+3+1=7),是所有符合條件的空地中最小的。
約束條件
- 網格的行數和列數均不超過 100。
- 網格中至少有一個建筑物。
LeetCode 317. 離建筑物最近的距離 詳細解題代碼
/*** @param {number[][]} grid* @return {number}*/
var shortestDistance = function(grid) {// 邊界條件判斷:網格為空或行數/列數為0if (!grid || grid.length === 0 || grid[0].length === 0) {return -1;}const rows = grid.length;const cols = grid[0].length;let buildingCount = 0; // 記錄建筑物的總數量// 存儲每個空地到所有建筑物的距離之和const distanceSum = Array.from({ length: rows }, () => Array(cols).fill(0));// 存儲每個空地能到達的建筑物數量const reachCount = Array.from({ length: rows }, () => Array(cols).fill(0));// 遍歷網格中的每個單元格for (let i = 0; i < rows; i++) {for (let j = 0; j < cols; j++) {// 當遇到建筑物時,執行BFS計算距離if (grid[i][j] === 1) {buildingCount++;const queue = [[i, j, 0]]; // BFS隊列,元素為[行, 列, 距離]const visited = Array.from({ length: rows }, () => Array(cols).fill(false));visited[i][j] = true; // 標記建筑物自身為已訪問// BFS循環while (queue.length > 0) {const [curRow, curCol, dist] = queue.shift(); // 取出隊首元素// 遍歷四個方向(上、下、左、右)const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];for (const [dr, dc] of directions) {const newRow = curRow + dr;const newCol = curCol + dc;// 檢查新坐標是否有效:在網格范圍內、未訪問過、且是空地if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols && !visited[newRow][newCol] && grid[newRow][newCol] === 0) {visited[newRow][newCol] = true; // 標記為已訪問distanceSum[newRow][newCol] += dist + 1; // 累加距離reachCount[newRow][newCol]++; // 增加可到達的建筑物數量queue.push([newRow, newCol, dist + 1]); // 加入隊列繼續BFS}}}}}}// 尋找最小的距離和let minDistance = Infinity;for (let i = 0; i < rows; i++) {for (let j = 0; j < cols; j++) {// 只有空地且能到達所有建筑物時,才參與最小距離計算if (grid[i][j] === 0 && reachCount[i][j] === buildingCount) {minDistance = Math.min(minDistance, distanceSum[i][j]);}}}// 如果沒有符合條件的空地,返回-1,否則返回最小距離return minDistance === Infinity ? -1 : minDistance;
};// 測試用例
const grid = [[1, 0, 2, 0, 1],[0, 0, 0, 0, 0],[0, 0, 1, 0, 0]
];
console.log(shortestDistance(grid)); // 輸出:7
代碼思路解析
- 初始化:創建兩個二維數組?
distanceSum
?和?reachCount
,分別用于記錄每個空地到所有建筑物的距離總和以及能到達的建筑物數量。 - BFS 遍歷:對每個建筑物執行 BFS,計算其到所有可達空地的距離,并更新?
distanceSum
?和?reachCount
。 - 篩選最優解:遍歷所有空地,找到能到達所有建筑物(
reachCount[i][j]
?等于建筑物總數)且距離總和最小的空地。 - 邊界處理:若不存在符合條件的空地,返回 -1,否則返回最小距離。
該解法通過 BFS 保證了距離計算的準確性,時間復雜度為 O (B×N×M)(其中 B 為建筑物數量,N 和 M 為網格的行數和列數),適用于題目給定的約束條件。