[Swift]LeetCode934. 最短的桥 | Shortest Bridge
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9903939.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
In a given 2D binary array A
, there are two islands. (An island is a 4-directionally connected group of 1
s not connected to any other 1s.)
Now, we may change 0
s to 1
s so as to connect the two islands together to form 1 island.
Return the smallest number of 0
s that must be flipped. (It is guaranteed that the answer is at least 1.)
Example 1:
Input: [[0,1],[1,0]]
Output: 1
Example 2:
Input: [[0,1,0],[0,0,0],[0,0,1]]
Output: 2
Example 3:
Input: [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
Output: 1
Note:
1 <= A.length = A[0].length <= 100
A[i][j] == 0
orA[i][j] == 1
在给定的二维二进制数组 A
中,存在两座岛。(岛是由四面相连的 1
形成的一个最大组。)
现在,我们可以将 0
变为 1
,以使两座岛连接起来,变成一座岛。
返回必须翻转的 0
的最小数目。(可以保证答案至少是 1。)
示例 1:
输入:[[0,1],[1,0]] 输出:1
示例 2:
输入:[[0,1,0],[0,0,0],[0,0,1]] 输出:2
示例 3:
输入:[[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]] 输出:1
提示:
1 <= A.length = A[0].length <= 100
A[i][j] == 0
或A[i][j] == 1
404ms
1 class Solution { 2 func shortestBridge(_ A: [[Int]]) -> Int { 3 let rowCount = A.count 4 if rowCount == 0 { 5 return 0 6 } 7 8 let colCount = A[0].count 9 10 var A = A 11 12 let coordinates = findFirstIsland(A: A) 13 let r1 = coordinates[0] 14 let c1 = coordinates[1] 15 16 var nextRiver = [Int]() 17 removeFirstIsland(A: &A, r: r1, c: c1, river: &nextRiver) 18 19 var distance = 0 20 while nextRiver.count > 0 { 21 let river = nextRiver 22 nextRiver = [Int]() 23 24 for coordinates in river { 25 let r = coordinates / rowCount 26 let c = coordinates % rowCount 27 28 let cell = A[r][c] 29 if cell == 0 { 30 A[r][c] = -1 31 32 if r > 0 { 33 // top 34 nextRiver.append((r - 1) * rowCount + c) 35 } 36 if (r + 1) < rowCount { 37 // bottom 38 nextRiver.append((r + 1) * rowCount + c) 39 } 40 if c > 0 { 41 nextRiver.append(r * rowCount + c - 1) 42 } 43 if (c + 1) < colCount { 44 nextRiver.append(r * rowCount + c + 1) 45 } 46 } else if cell == 1 { 47 return distance 48 } 49 } 50 distance += 1 51 } 52 return distance 53 } 54 55 func removeFirstIsland(A: inout [[Int]], r: Int, c: Int, river: inout [Int]) { 56 let rowCount = A.count 57 let colCount = A[0].count 58 59 let cell = A[r][c] 60 if cell == 0 { 61 // A[r][c] = 2 62 river.append(r * rowCount + c) 63 return 64 } else if cell == -1 { 65 return 66 } 67 A[r][c] = -1 68 69 if r > 0 { 70 // top 71 removeFirstIsland(A: &A, r: r - 1, c: c, river: &river) 72 } 73 if (r + 1) < rowCount { 74 // bottom 75 removeFirstIsland(A: &A, r: r + 1, c: c, river: &river) 76 } 77 if c > 0 { 78 removeFirstIsland(A: &A, r: r, c: c - 1, river: &river) 79 } 80 if (c + 1) < colCount { 81 removeFirstIsland(A: &A, r: r, c: c + 1, river: &river) 82 } 83 } 84 85 func findFirstIsland(A: [[Int]]) -> [Int] { 86 let rowCount = A.count 87 let colCount = A[0].count 88 var coordinates = Array(repeating: 0, count: 2) 89 var r = 0 90 var c = 0 91 while r < rowCount { 92 c = 0 93 while c < colCount { 94 if A[r][c] == 1 { 95 coordinates[0] = r 96 coordinates[1] = c 97 return coordinates 98 } 99 c += 1 100 } 101 r += 1 102 } 103 return coordinates 104 } 105 }
428ms
1 class Solution { 2 func shortestBridge(_ A: [[Int]]) -> Int { 3 var a = A 4 var q = [(Int, Int)]() 5 6 loop: for i in 0 ..< A.count { 7 for j in 0 ..< A[i].count { 8 if A[i][j] == 1 { 9 dfs(&a, i, j, &q) 10 break loop 11 } 12 } 13 } 14 15 let dir = [0 , 1 , 0 , -1 , 0] 16 var step = 0 17 while !q.isEmpty { 18 19 var size = q.count 20 while size > 0 { 21 let (i, j) = q.removeFirst() 22 for index in 0 ..< 4 { 23 let ti = i + dir[index] 24 let tj = j + dir[index + 1] 25 if ti < 0 || ti >= a.count || tj < 0 || tj >= a[i].count || a[ti][tj] == 2 { 26 continue 27 } 28 if a[ti][tj] == 1 { 29 return step 30 } else { 31 a[ti][tj] = 2 32 q.append((ti,tj)) 33 34 } 35 } 36 size -= 1 37 } 38 step += 1 39 } 40 41 return -1 42 } 43 44 func dfs(_ A: inout [[Int]], _ i: Int, _ j: Int, _ q: inout [(Int, Int)]) { 45 if i < 0 || i >= A.count || j < 0 || j >= A[i].count || A[i][j] != 1 { 46 return 47 } else { 48 A[i][j] = 2 49 q.append((i, j)) 50 dfs(&A, i - 1, j, &q) 51 dfs(&A, i + 1, j, &q) 52 dfs(&A, i, j - 1, &q) 53 dfs(&A, i, j + 1, &q) 54 } 55 } 56 }
476ms
1 class Solution { 2 func shortestBridge(_ A: [[Int]]) -> Int { 3 let R = A.count 4 let C = A[0].count 5 var qs = [(Int, Int)]() 6 var color = 1 7 var v = [[Int]](repeating: [Int](repeating: 0, count: C), count: R) 8 var ans = 0 9 func next(_ r: Int, _ c: Int, _ d: inout [String: (Int, Int)]) -> Bool { 10 var ns = [(r+1, c), (r-1, c), (r, c+1), (r, c-1)] 11 for n in ns { 12 guard 0 ..< R ~= n.0, 0 ..< C ~= n.1 else { 13 continue 14 } 15 guard v[n.0][n.1] == 0 else { 16 if v[n.0][n.1] != v[r][c] { 17 //print(n, r, c) 18 return true 19 } 20 continue 21 } 22 v[n.0][n.1] = v[r][c] 23 d["\(n.0), \(n.1)"] = (n.0, n.1) 24 } 25 return false 26 } 27 func paint(_ r: Int, _ c: Int) { 28 guard v[r][c] == 0 else { 29 return 30 } 31 v[r][c] = color 32 var qs = [(r, c)] 33 while !qs.isEmpty { 34 for i in 0 ..< qs.count { 35 let (r, c) = qs.remove(at: 0) 36 let ns = [(r+1, c), (r-1, c), (r, c+1), (r, c-1)] 37 for n in ns { 38 guard 0 ..< R ~= n.0, 0 ..< C ~= n.1 else { 39 continue 40 } 41 guard v[n.0][n.1] == 0, A[n.0][n.1] == 1 else { 42 continue 43 } 44 v[n.0][n.1] = color 45 qs.append(n) 46 } 47 } 48 } 49 color += 1 50 } 51 for r in 0 ..< R { 52 for c in 0 ..< C { 53 if A[r][c] == 1 { 54 paint(r, c) 55 if v[r][c] == 1 { 56 qs.append((r, c)) 57 } 58 } 59 } 60 } 61 //print(v) 62 while !qs.isEmpty { 63 //print(qs) 64 var d = [String: (Int, Int)]() 65 for i in 0 ..< qs.count { 66 let (r, c) = qs.remove(at: 0) 67 guard next(r, c, &d) == false else { 68 //print(v) 69 return ans 70 } 71 } 72 ans += 1 73 qs = Array(d.values) 74 } 75 76 return ans 77 } 78 }
484ms
1 class Solution { 2 struct Coor { 3 var x:Int; 4 var y:Int; 5 } 6 var visited:[[Bool]] = [[Bool]](); 7 var grids:[[Int]]!; 8 func shortestBridge(_ A: [[Int]]) -> Int { 9 var step:Int = -1; 10 grids = A; 11 for i in 0 ..< A.count{ 12 let oneRow = Array<Bool>(repeating: false, count: A[i].count); 13 visited.append(oneRow); 14 } 15 var i = 0; 16 var j = 0; 17 for ii in 0 ..< A.count{ 18 for jj in 0 ..< A[ii].count{ 19 if (A[ii][jj] == 1){ 20 i = ii; 21 j = jj; 22 break; 23 } 24 } 25 } 26 let island_A = completeThisIsland(x: i, y: j); 27 // resetVisited() 28 var queue = Array<Coor>(); 29 var steps = Array<Int>(repeating: 0, count: island_A.count); 30 queue.append(contentsOf: island_A); 31 var found = false; 32 while (!found){ 33 let co = queue.removeFirst(); 34 let thisStep = steps.removeFirst(); 35 let neighbors = [Coor(x: co.x-1, y: co.y),Coor(x: co.x+1, y: co.y),Coor(x: co.x, y: co.y+1),Coor(x:co.x,y:co.y-1)]; 36 for neighbor in neighbors{ 37 if valid(coor: neighbor) && !visited[neighbor.x][neighbor.y]{ 38 if grids[neighbor.x][neighbor.y] == 1{ 39 step = thisStep; 40 found = true; 41 break; 42 }else{ 43 queue.append(neighbor) 44 steps.append(thisStep+1) 45 visited[neighbor.x][neighbor.y] = true; 46 } 47 // queue.append(neighbor); 48 // visited[neighbor.x][neighbor.y] = true; 49 } 50 } 51 } 52 53 return step; 54 } 55 func resetVisited() -> Void { 56 for var i in visited{ 57 for j in 0 ..< i.count{ 58 i[j] = false; 59 } 60 } 61 } 62 func valid(coor:Coor) -> Bool { 63 return coor.x > -1 && coor.x < grids.count && coor.y > -1 && coor.y < grids[coor.x].count; 64 } 65 func completeThisIsland(x:Int,y:Int) -> [Coor] { 66 var result = [Coor](); 67 var queue = [Coor](); 68 queue.append(Coor(x: x, y: y)) 69 visited[x][y] = true; 70 while(!queue.isEmpty){ 71 let co = queue.removeFirst(); 72 // visited[co.x][co.y] = true; 73 result.append(co); 74 let neighbors = [Coor(x: co.x-1, y: co.y),Coor(x: co.x+1, y: co.y),Coor(x: co.x, y: co.y+1),Coor(x:co.x,y:co.y-1)]; 75 for neighbor in neighbors{ 76 if valid(coor: neighbor) && grids[neighbor.x][neighbor.y] == 1 && !visited[neighbor.x][neighbor.y]{ 77 queue.append(neighbor); 78 visited[neighbor.x][neighbor.y] = true; 79 } 80 } 81 } 82 return result; 83 } 84 }
624ms
1 class Solution { 2 func shortestBridge(_ A: [[Int]]) -> Int { 3 var a = A 4 //print(A) 5 var edI = -1 6 var edJ = -1 7 for i in (0..<A.count) { 8 for j in (0..<A[i].count) { 9 if A[i][j] == 1 { 10 edI = i 11 edJ = j 12 break 13 } 14 } 15 if edI != -1 { break } 16 } 17 18 //print(edI, edJ) 19 bfs(&a, edI, edJ) 20 21 for i in (0..<a.count) { 22 for j in (0..<a[i].count) { 23 if a[i][j] == 1 { 24 a[i][j] = -2 25 } 26 } 27 } 28 //print(a) 29 30 return dfs(&a, edI, edJ) - 1 31 } 32 33 func bfs(_ A: inout [[Int]], _ i: Int, _ j: Int) { 34 A[i][j] = -1 35 if i+1 < A.count && A[i+1][j] == 1 { 36 A[i+1][j] = -1 37 bfs(&A, i+1, j) 38 } 39 40 if j + 1 < A[i].count && A[i][j+1] == 1 { 41 A[i][j+1] = -1 42 bfs(&A, i, j+1) 43 } 44 45 if i > 0 && A[i-1][j] == 1 { 46 A[i-1][j] = -1 47 bfs(&A, i-1, j) 48 } 49 50 if j > 0 && A[i][j-1] == 1 { 51 A[i][j-1] = -1 52 bfs(&A, i, j-1) 53 } 54 } 55 56 func dfs(_ A: inout [[Int]], _ i: Int, _ j: Int) -> Int { 57 var queue: [Int] = [] 58 queue.append(i * 200 + j) 59 while queue.count > 0 { 60 //print(queue) 61 //print(A) 62 let curI = queue[0] / 200 63 let curJ = queue[0] % 200 64 if A[curI][curJ] == -1 { A[curI][curJ] = -3 } 65 queue.remove(at: 0) 66 if curI+1 < A.count { 67 if A[curI+1][curJ] == -2 { 68 return A[curI][curJ] + 1 69 } else if A[curI+1][curJ] == -1 { 70 queue.insert((curI+1)*200+curJ, at: 0) 71 } else if A[curI+1][curJ] == 0 { 72 if A[curI][curJ] < 0 { 73 A[curI+1][curJ] = 1 74 } else { 75 A[curI+1][curJ] = A[curI][curJ] + 1 76 } 77 queue.append((curI+1)*200+curJ) 78 } 79 } 80 81 if curJ+1 < A[curI].count { 82 if A[curI][curJ+1] == -2 { 83 return A[curI][curJ] + 1 84 } else if A[curI][curJ+1] == -1 { 85 queue.insert((curI)*200+curJ+1, at: 0) 86 } else if A[curI][curJ+1] == 0 { 87 if A[curI][curJ] < 0 { 88 A[curI][curJ+1] = 1 89 } else { 90 A[curI][curJ+1] = A[curI][curJ] + 1 91 } 92 queue.append((curI)*200+curJ+1) 93 } 94 } 95 96 if curI > 0 { 97 if A[curI-1][curJ] == -2 { 98 return A[curI][curJ] + 1 99 } else if A[curI-1][curJ] == -1 { 100 queue.insert((curI-1)*200+curJ, at: 0) 101 } else if A[curI-1][curJ] == 0 { 102 if A[curI][curJ] < 0 { 103 A[curI-1][curJ] = 1 104 } else { 105 A[curI-1][curJ] = A[curI][curJ] + 1 106 } 107 queue.append((curI-1)*200+curJ) 108 } 109 } 110 111 if curJ > 0 { 112 if A[curI][curJ-1] == -2 { 113 return A[curI][curJ] + 1 114 } else if A[curI][curJ-1] == -1 { 115 queue.insert((curI)*200+curJ-1, at: 0) 116 } else if A[curI][curJ-1] == 0 { 117 if A[curI][curJ] < 0 { 118 A[curI][curJ-1] = 1 119 } else { 120 A[curI][curJ-1] = A[curI][curJ] + 1 121 } 122 queue.append((curI)*200+curJ-1) 123 } 124 } 125 126 } 127 return 0 128 } 129 }
648ms
1 class Solution { 2 func shortestBridge(_ A: [[Int]]) -> Int { 3 var n:Int = A.count, m = A[0].count 4 var can:[[Bool]] = [[Bool]](repeating: [Bool](repeating: false, count: m), count: n) 5 var dr:[Int] = [1, 0, -1, 0 ] 6 var dc:[Int] = [0, 1, 0, -1 ] 7 var d:[[Int]] = [[Int]](repeating: [Int](repeating: 99999999, count: m), count: n) 8 9 var gq:Queue<[Int]> = Queue<[Int]>() 10 inner: 11 for i in 0..<n 12 { 13 for j in 0..<m 14 { 15 if A[i][j] == 1 16 { 17 var q:Queue<[Int]> = Queue<[Int]>() 18 q.enQueue([i,j]) 19 can[i][j] = true 20 while(!q.isEmpty()) 21 { 22 var cur:[Int] = q.deQueue()! 23 gq.enQueue(cur) 24 var r:Int = cur[0], c:Int = cur[1] 25 d[r][c] = 0 26 for k in 0..<4 27 { 28 var nr:Int = r + dr[k], nc:Int = c + dc[k] 29 if nr >= 0 && nr < n && nc >= 0 && nc < m && A[nr][nc] == 1 && !can[nr][nc] 30 { 31 can[nr][nc] = true 32 q.enQueue([nr, nc]) 33 } 34 } 35 } 36 break inner 37 } 38 } 39 } 40 41 while(!gq.isEmpty()) 42 { 43 var cur:[Int] = gq.deQueue()! 44 var r:Int = cur[0], c:Int = cur[1] 45 for k in 0..<4 46 { 47 var nr:Int = r + dr[k], nc:Int = c + dc[k] 48 if nr >= 0 && nr < n && nc >= 0 && nc < m && d[nr][nc] > d[r][c] + 1 49 { 50 d[nr][nc] = d[r][c] + 1 51 gq.enQueue([nr, nc]) 52 } 53 } 54 } 55 var ret:Int = 9999999 56 for i in 0..<n 57 { 58 for j in 0..<m 59 { 60 if !can[i][j] && A[i][j] == 1 61 { 62 ret = min(ret, d[i][j]) 63 } 64 } 65 } 66 return ret-1 67 } 68 } 69 70 public struct Queue<T> { 71 72 // 泛型数组:用于存储数据元素 73 fileprivate var queue: [T] 74 75 // 返回队列中元素的个数 76 public var count: Int { 77 return queue.count 78 } 79 80 // 构造函数:创建一个空的队列 81 public init() { 82 queue = [T]() 83 } 84 85 //通过既定数组构造队列 86 init(_ arr:[T]){ 87 queue = arr 88 } 89 90 // 如果定义了默认值,则可以在调用函数时省略该参数 91 init(_ elements: T...) { 92 queue = elements 93 } 94 95 // 检查队列是否为空 96 // - returns: 如果队列为空,则返回true,否则返回false 97 public func isEmpty() -> Bool { 98 return queue.isEmpty 99 } 100 101 // 入队列操作:将元素添加到队列的末尾 102 public mutating func enQueue(_ element: T) { 103 queue.append(element) 104 } 105 106 // 出队列操作:删除并返回队列中的第一个元素 107 public mutating func deQueue() -> T? { 108 return queue.removeFirst() 109 } 110 }