[Swift]LeetCode733. 圖像渲染 | Flood Fill

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-bhghortb-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).git

Given a coordinate (sr, sc) representing the starting pixel (row and column) of the flood fill, and a pixel value newColor, "flood fill" the image.github

To perform a "flood fill", consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color as the starting pixel), and so on. Replace the color of all of the aforementioned pixels with the newColor.數組

At the end, return the modified image.微信

Example 1:app

Input: 
image = [[1,1,1],[1,1,0],[1,0,1]]
sr = 1, sc = 1, newColor = 2
Output: [[2,2,2],[2,2,0],[2,0,1]]
Explanation: 
From the center of the image (with position (sr, sc) = (1, 1)), all pixels connected 
by a path of the same color as the starting pixel are colored with the new color.
Note the bottom corner is not colored 2, because it is not 4-directionally connected
to the starting pixel. 

Note:ide

  • The length of image and image[0] will be in the range [1, 50].
  • The given starting pixel will satisfy 0 <= sr < image.length and 0 <= sc < image[0].length.
  • The value of each color in image[i][j] and newColor will be an integer in [0, 65535].

有一幅以二維整數數組表示的圖畫,每個整數表示該圖畫的像素值大小,數值在 0 到 65535 之間。this

給你一個座標 (sr, sc) 表示圖像渲染開始的像素值(行 ,列)和一個新的顏色值 newColor,讓你從新上色這幅圖像。spa

爲了完成上色工做,從初始座標開始,記錄初始座標的上下左右四個方向上像素值與初始座標相同的相連像素點,接着再記錄這四個方向上符合條件的像素點與他們對應四個方向上像素值與初始座標相同的相連像素點,……,重複該過程。將全部有記錄的像素點的顏色值改成新的顏色值。code

最後返回通過上色渲染後的圖像。

示例 1:

輸入: 
image = [[1,1,1],[1,1,0],[1,0,1]]
sr = 1, sc = 1, newColor = 2
輸出: [[2,2,2],[2,2,0],[2,0,1]]
解析: 
在圖像的正中間,(座標(sr,sc)=(1,1)),
在路徑上全部符合條件的像素點的顏色都被更改爲2。
注意,右下角的像素沒有更改成2,
由於它不是在上下左右四個方向上與初始點相連的像素點。

注意:

  • image 和 image[0] 的長度在範圍 [1, 50] 內。
  • 給出的初始點將知足 0 <= sr < image.length和 0 <= sc < image[0].length
  • image[i][j] 和 newColor 表示的顏色值在範圍 [0, 65535]內。

Runtime: 64 ms
Memory Usage: 19.2 MB
 1 class Solution {
 2     
 3     func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {
 4         if image.count == 0 || image[0].count == 0 { return [] }
 5         var image = image
 6         
 7         let curColor = image[sr][sc]
 8         floodFillHelper(&image, sr, sc, curColor, newColor)
 9         
10         return image
11     }
12     
13     func floodFillHelper(_ image: inout [[Int]], _ sr: Int, _ sc: Int, _ curColor: Int, _ newColor: Int) {
14         if sr < 0 || sr >= image.count || 
15         sc < 0 || sc >= image[0].count || 
16         image[sr][sc] != curColor || image[sr][sc] == newColor{ return }
17 
18         image[sr][sc] = newColor
19 
20         floodFillHelper(&image, sr-1, sc, curColor, newColor)   
21         floodFillHelper(&image, sr+1, sc, curColor, newColor)           
22         floodFillHelper(&image, sr, sc-1, curColor, newColor)   
23         floodFillHelper(&image, sr, sc+1, curColor, newColor)       
24     }    
25 }

80ms

 1 class Solution {
 2     
 3     func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {
 4         if image.count == 0 || image[0].count == 0 { return [] }
 5         var image = image
 6         
 7         let curColor = image[sr][sc]
 8         floodFillHelper(&image, sr, sc, curColor, newColor)
 9         
10         return image
11     }
12     
13     func floodFillHelper(_ image: inout [[Int]], _ sr: Int, _ sc: Int, _ curColor: Int, _ newColor: Int) {
14         if sr < 0 || sr >= image.count || sc < 0 || sc >= image[0].count { return }
15         if image[sr][sc] != curColor || image[sr][sc] == newColor { return }
16 
17 
18         image[sr][sc] = newColor
19 
20         for i in -1...1 {
21             floodFillHelper(&image, sr+i, sc, curColor, newColor)       
22             floodFillHelper(&image, sr, sc+i, curColor, newColor)       
23         }    
24     }    
25 }

84ms

 1 class Solution {
 2     func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {
 3         let m = image.count
 4         let n = image.first?.count ?? 0
 5         
 6         var image = image
 7         var stack = [[Int]]()
 8         var visited = Set<[Int]>()
 9         stack.append([sr,sc])
10         let startColor = image[sr][sc]
11         
12         while !stack.isEmpty {
13             let pos = stack.removeLast()
14             visited.insert(pos)
15             let vr = pos[0]
16             let vc = pos[1]
17             image[vr][vc] = newColor
18             
19             let directions = [
20                 [1, 0],
21                 [-1, 0],
22                 [0, 1],
23                 [0, -1]
24             ]
25             
26             for d in directions {
27                 let r = vr + d[0]
28                 let c = vc + d[1]
29 
30                 if r < 0 || c < 0 || r >= m || c >= n || image[r][c] != startColor || visited.contains([r,c]) {
31                     continue
32                 }
33                 stack.append([r,c])
34             }
35         }
36         
37         return image
38     }
39 }

88ms

 1 class Solution {
 2     func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {
 3         guard image.count > 0 else { return [] }
 4         var res = image
 5         var queue = [[sr, sc]]
 6         var j = 0
 7         let color = image[sr][sc]
 8         var visited = Set<[Int]>()
 9         while j != queue.count {
10             let current = queue[j]
11             j += 1
12             visited.insert(current)
13             res[current[0]][current[1]] = newColor
14             queue += neighbours(image, current, color, visited)
15         }
16         return res
17     }
18     
19     func neighbours(_ image: [[Int]], _ p: [Int], _ color: Int, _ visited: Set<[Int]>) -> [[Int]] {
20         let rows = image.count, cols = image[0].count
21         let x = p[0], y = p[1]
22         return [[x-1, y], [x+1, y], [x, y-1], [x, y+1]].filter { !visited.contains($0) && $0[0] >= 0 && $0[0] < rows && $0[1] >= 0 && $0[1] < cols && image[$0[0]][$0[1]] == color }
23     }
24 }

100ms

 1 class Solution {   
 2     func emptyImageGrid(_ image: [[Int]]) -> [[Int]] {
 3         var grid = [[Int]]()
 4         for i in 0..<image.count {
 5             var row = [Int]()
 6             for _ in 0..<image[i].count {
 7                 row.append(0)
 8             }
 9             grid.append(row)
10         }
11         return grid
12     }
13     func shouldAdd(_ image: [[Int]], _ visited: Set<MAPoint>, _ sr: Int, _ sc: Int, _ desiredColor: Int) -> Bool {
14         if sr >= 0 && sr < image.count && sc >= 0 && sc < image[sr].count {
15             // this is a valid point in the graph
16             if image[sr][sc] == desiredColor && visited.contains(MAPoint(row: sr, col: sc)) == false {
17                 // this point is the right color and hasn't been visited yet
18                 return true
19             }
20         }
21         return false
22     }
23     func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {
24         let originalColor = image[sr][sc]
25         var imageGrid = image
26         var points = [Int]()
27         var queue = [MAPoint]()
28         var visited = Set<MAPoint>()
29         queue.append(MAPoint(row: sr, col: sc))
30         while let firstPoint = queue.first {
31             imageGrid[firstPoint.row][firstPoint.col] = newColor
32             visited.insert(firstPoint)
33             queue.removeFirst()
34             // check surroundings
35             if shouldAdd(image, visited, firstPoint.row, firstPoint.col-1, originalColor) == true {
36                 // left
37                 queue.append(MAPoint(row: firstPoint.row, col: firstPoint.col-1))
38             }
39             if shouldAdd(image, visited, firstPoint.row, firstPoint.col+1, originalColor) == true {
40                 // right
41                 queue.append(MAPoint(row: firstPoint.row, col: firstPoint.col+1))
42             }
43             if shouldAdd(image, visited, firstPoint.row-1, firstPoint.col, originalColor) == true {
44                 // up
45                 queue.append(MAPoint(row: firstPoint.row-1, col: firstPoint.col))
46             }
47             if shouldAdd(image, visited, firstPoint.row+1, firstPoint.col, originalColor) == true {
48                 // down
49                 queue.append(MAPoint(row: firstPoint.row+1, col: firstPoint.col))
50             }
51         }
52         return imageGrid
53     }
54 }
55 
56 struct MAPoint {
57     let row: Int
58     let col: Int
59 }
60 
61 extension MAPoint: Hashable {
62     static func == (lhs: MAPoint, rhs: MAPoint) -> Bool {
63         return lhs.row == rhs.row && lhs.col == rhs.col
64     }
65     func hash(into hasher: inout Hasher) {
66         hasher.combine(row)
67         hasher.combine(col)
68     }
69 }

100ms

 1 class Solution {
 2     func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {    
 3         var resImage: [[Int]] = image
 4         var oldColor: Int = image[sr][sc]
 5         
 6         guard oldColor != newColor else {
 7             return image
 8         }   
 9         func setNewColor(_ sr: Int, _ sc: Int) {
10             resImage[sr][sc] = newColor
11             if sr > 0 && resImage[sr - 1][sc] == oldColor {
12                 setNewColor(sr - 1, sc)
13             }
14             if sr < image.count - 1 && resImage[sr + 1][sc] == oldColor {
15                 setNewColor(sr + 1, sc)
16             }
17             if sc > 0 && resImage[sr][sc - 1] == oldColor {
18                 setNewColor(sr, sc - 1)
19             }
20             if sc < image[0].count - 1 && resImage[sr][sc + 1] == oldColor {
21                 setNewColor(sr, sc + 1)
22             }
23         }       
24         setNewColor(sr, sc)  
25         return resImage
26     }
27 }
相關文章
相關標籤/搜索