[Swift]LeetCode994. 腐烂的橘子 | Rotting Oranges
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10390715.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
In a given grid, each cell can have one of three values:
- the value
0
representing an empty cell; - the value
1
representing a fresh orange; - the value
2
representing a rotten orange.
Every minute, any fresh orange that is adjacent (4-directionally) to a rotten orange becomes rotten.
Return the minimum number of minutes that must elapse until no cell has a fresh orange. If this is impossible, return -1
instead.
Example 1:
Input: [[2,1,1],[1,1,0],[0,1,1]]
Output: 4
Example 2:
Input: [[2,1,1],[0,1,1],[1,0,1]]
Output: -1
Explanation: The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally.
Example 3:
Input: [[0,2]]
Output: 0
Explanation: Since there are already no fresh oranges at minute 0, the answer is just 0.
Note:
1 <= grid.length <= 10
1 <= grid[0].length <= 10
grid[i][j]
is only0
,1
, or2
.
在给定的网格中,每个单元格可以有以下三个值之一:
- 值
0
代表空单元格; - 值
1
代表新鲜橘子; - 值
2
代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1
。
示例 1:
输入:[[2,1,1],[1,1,0],[0,1,1]] 输出:4
示例 2:
输入:[[2,1,1],[0,1,1],[1,0,1]] 输出:-1 解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
示例 3:
输入:[[0,2]] 输出:0 解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
提示:
1 <= grid.length <= 10
1 <= grid[0].length <= 10
grid[i][j]
仅为0
、1
或2
1 class Solution { 2 func orangesRotting(_ grid: [[Int]]) -> Int { 3 if grid.isEmpty { 4 return -1 5 } 6 var grid = grid 7 var grid1 = grid 8 9 let yy = grid.count 10 let xx = grid[0].count 11 12 var mins = 0 13 14 while true { 15 var noFresh = true 16 var processStopped = true 17 18 for i in 0..<yy { 19 for j in 0..<xx { 20 let x = grid[i][j] 21 22 if x == 1 { 23 noFresh = false 24 if isNextRotten(grid, row: i, column: j) { 25 grid1[i][j] = 2 26 processStopped = false 27 } 28 } 29 } 30 } 31 32 if noFresh { 33 return mins 34 } 35 36 if processStopped { 37 return -1 38 } 39 40 grid = grid1 41 mins += 1 42 } 43 44 return -1 45 } 46 47 func isNextRotten(_ grid: [[Int]], row i: Int, column j: Int) -> Bool { 48 if i > 0 { 49 if grid[i - 1][j] == 2 { 50 return true 51 } 52 } 53 54 if i < grid.count - 1 { 55 if grid[i + 1][j] == 2 { 56 return true 57 } 58 } 59 60 if j > 0 { 61 if grid[i][j - 1] == 2 { 62 return true 63 } 64 } 65 66 if j < grid[0].count - 1 { 67 if grid[i][j + 1] == 2 { 68 return true 69 } 70 } 71 72 return false 73 } 74 }
1 class Solution { 2 var D:[[Int]] = [[-1, 0],[1, 0],[0, -1],[0, 1]] 3 func orangesRotting(_ grid: [[Int]]) -> Int { 4 var R:Int = grid.count 5 var C:Int = grid[0].count 6 var ans:[[Int]] = [[Int]](repeating:[Int](repeating:0,count:C),count:R) 7 for i in 0..<R 8 { 9 for j in 0..<C 10 { 11 if grid[i][j] == 2 12 { 13 bfs(grid, &ans, i, j) 14 } 15 } 16 } 17 var res:Int = 0 18 for i in 0..<R 19 { 20 for j in 0..<C 21 { 22 if grid[i][j] == 1 23 { 24 if ans[i][j] == 0 25 { 26 return -1 27 } 28 res = max(res, ans[i][j]) 29 } 30 31 } 32 } 33 return res 34 } 35 36 func bfs(_ grid: [[Int]],_ ans: inout [[Int]],_ sx:Int,_ sy:Int) 37 { 38 var R:Int = grid.count 39 var C:Int = grid[0].count 40 var q:[[Int]] = [[Int]]() 41 q.append([sx,sy,0]) 42 while(!q.isEmpty) 43 { 44 var cur:[Int] = q.removeFirst() 45 var cost:Int = cur[2] + 1 46 for d in D 47 { 48 var x:Int = cur[0] + d[0] 49 var y:Int = cur[1] + d[1] 50 if x >= 0 && y >= 0 && x < R && y < C && grid[x][y] == 1 && (ans[x][y] == 0 || ans[x][y] > cost) 51 { 52 ans[x][y] = cost 53 q.append([x,y,cost]) 54 } 55 } 56 } 57 } 58 }
28ms
1 class Solution { 2 func orangesRotting(_ grid: [[Int]]) -> Int { 3 guard grid.count > 0 else { 4 return 0 5 } 6 guard grid[0].count > 0 else { 7 return 0 8 } 9 10 var count = 0 11 12 for i in grid.indices { 13 for j in grid[0].indices { 14 if grid[i][j] == 0 || grid[i][j] == 2 { 15 count += 1 16 } 17 } 18 } 19 20 var step = 0 21 22 var isEnd = false 23 var grid = grid 24 let countL = grid.count 25 let countC = grid[0].count 26 27 while !isEnd { 28 isEnd = true 29 30 var changed: [[Int]] = Array.init(repeating: Array.init(repeating: 0, count: countC), count: countL) 31 32 for i in 0..<countL { 33 for j in 0..<countC { 34 if grid[i][j] == 2 && changed[i][j] == 0 { 35 if i > 0 && grid[i - 1][j] == 1 { 36 grid[i - 1][j] = 2 37 changed[i - 1][j] = 1 38 isEnd = false 39 count += 1 40 } 41 if j > 0 && grid[i][j - 1] == 1 { 42 grid[i][j - 1] = 2 43 changed[i][j - 1] = 1 44 isEnd = false 45 count += 1 46 } 47 if i + 1 < countL && grid[i + 1][j] == 1 { 48 grid[i + 1][j] = 2 49 changed[i + 1][j] = 1 50 isEnd = false 51 count += 1 52 } 53 if j + 1 < countC && grid[i][j + 1] == 1 { 54 grid[i][j + 1] = 2 55 changed[i][j + 1] = 1 56 isEnd = false 57 count += 1 58 } 59 } 60 } 61 } 62 63 if isEnd == false { 64 step += 1 65 } 66 } 67 68 if count != countL * countC { 69 step = -1 70 } 71 72 return step 73 } 74 }
32ms
1 class Solution { 2 3 func orangesRotting(_ grid: [[Int]]) -> Int { 4 if grid.isEmpty { 5 return -1 6 } 7 8 var grid = grid 9 var grid1 = grid 10 11 let rows = grid.count 12 let columns = grid[0].count 13 14 var mins = 0 15 16 while true { 17 var noFresh = true 18 var noProcess = true 19 20 for i in 0..<rows { 21 for j in 0..<columns { 22 let x = grid[i][j] 23 24 if x == 1 { 25 noFresh = false 26 27 if isRottenNearly(grid, row: i, col: j) { 28 noProcess = false 29 grid1[i][j] = 2 30 } 31 } 32 } 33 } 34 35 if noFresh { 36 return mins 37 } 38 39 if noProcess { 40 return -1 41 } 42 43 mins += 1 44 grid = grid1 45 } 46 47 return -1 48 } 49 50 func isRottenNearly(_ grid: [[Int]], row i: Int, col j: Int) -> Bool { 51 if i > 0 { // n 52 if grid[i - 1][j] == 2 { 53 return true 54 } 55 } 56 57 if j > 0 { // w 58 if grid[i][j - 1] == 2 { 59 return true 60 } 61 } 62 63 if i < grid.count - 1 { // s 64 if grid[i + 1][j] == 2 { 65 return true 66 } 67 } 68 69 if j < grid[0].count - 1 { // e 70 if grid[i][j + 1] == 2 { 71 return true 72 } 73 } 74 return false 75 } 76 }
36ms
1 class Solution { 2 func orangesRotting(_ originalGrid: [[Int]]) -> Int { 3 guard originalGrid.count > 0, originalGrid[0].count > 0 else { return -1 } 4 var grid = [[Int]](repeating: Array(repeating: -1, count: originalGrid[0].count), count: originalGrid.count) 5 var minutes = 0 6 for r in 0..<originalGrid.count { 7 for c in 0..<originalGrid[0].count { 8 if originalGrid[r][c] == 1 { 9 grid[r][c] = Int.max 10 } else if originalGrid[r][c] == 2 { 11 grid[r][c] = 0 12 } 13 } 14 } 15 for r in 0..<grid.count { 16 for c in 0..<grid[0].count { 17 if grid[r][c] == 0 { 18 bfs(&grid, r, c) 19 } 20 } 21 } 22 var res = 0 23 for r in 0..<grid.count { 24 for c in 0..<grid[0].count { 25 res = max(res, grid[r][c]) 26 } 27 } 28 return res == Int.max ? -1 : res 29 } 30 31 func bfs(_ grid: inout [[Int]], _ r: Int, _ c: Int) { 32 var q = Queue<(Int, Int)>() 33 var visited: [[Bool]] = Array(repeating: Array(repeating: false, count: grid[0].count), count: grid.count) 34 q.push((r, c)) 35 while !q.isEmpty { 36 let (row, col) = q.pop() 37 if row > 0 && grid[row - 1][col] > 0 && visited[row - 1][col] == false { 38 grid[row - 1][col] = min(grid[row - 1][col], grid[row][col] + 1) 39 q.push((row - 1, col)) 40 } 41 if (row + 1) < grid.count && grid[row + 1][col] > 0 && visited[row + 1][col] == false { 42 grid[row + 1][col] = min(grid[row + 1][col], grid[row][col] + 1) 43 q.push((row + 1, col)) 44 } 45 if col > 0 && grid[row][col - 1] > 0 && visited[row][col - 1] == false { 46 grid[row][col - 1] = min(grid[row][col - 1], grid[row][col] + 1) 47 q.push((row, col - 1)) 48 } 49 if (col + 1) < grid[0].count && grid[row][col + 1] > 0 && visited[row ][col + 1] == false { 50 grid[row][col + 1] = min(grid[row][col + 1], grid[row][col] + 1) 51 q.push((row, col + 1)) 52 } 53 visited[row][col] = true 54 } 55 } 56 } 57 58 struct Queue<T> { 59 var arr: [T] = [] 60 var head = 0 61 62 mutating func push(_ val: T) { 63 arr.append(val) 64 } 65 66 mutating func pop() -> T { 67 let res = arr[head] 68 head += 1 69 return res 70 } 71 72 var isEmpty: Bool { 73 return head >= arr.count 74 } 75 76 var size: Int { 77 return arr.count - head 78 } 79 }