为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode994. 腐烂的橘子 | Rotting Oranges

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10390715.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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. 1 <= grid.length <= 10
  2. 1 <= grid[0].length <= 10
  3. grid[i][j] is only 01, or 2.

在给定的网格中,每个单元格可以有以下三个值之一:

  • 值 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. 1 <= grid.length <= 10
  2. 1 <= grid[0].length <= 10
  3. grid[i][j] 仅为 01 或 2

24ms
 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 }

Runtime: 28 ms
Memory Usage: 19.3 MB
 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 }

 

posted @ 2019-02-17 12:37  为敢技术  阅读(588)  评论(0编辑  收藏  举报