[Swift]LeetCode1210. 穿過迷宮的最少移動次數 | Minimum Moves to Reach Target with Rotations

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

In an n*n grid, there is a snake that spans 2 cells and starts moving from the top left corner at (0, 0) and (0, 1). The grid has empty cells represented by zeros and blocked cells represented by ones. The snake wants to reach the lower right corner at (n-1, n-2) and (n-1, n-1).git

In one move the snake can:github

  • Move one cell to the right if there are no blocked cells there. This move keeps the horizontal/vertical position of the snake as it is.
  • Move down one cell if there are no blocked cells there. This move keeps the horizontal/vertical position of the snake as it is.
  • Rotate clockwise if it's in a horizontal position and the two cells under it are both empty. In that case the snake moves from (r, c) and (r, c+1) to (r, c) and (r+1, c).
  • Rotate counterclockwise if it's in a vertical position and the two cells to its right are both empty. In that case the snake moves from (r, c) and (r+1, c) to (r, c) and (r, c+1).

Return the minimum number of moves to reach the target.微信

If there is no way to reach the target, return -1.app

 

Example 1:spa

Input: grid = [[0,0,0,0,0,1],
               [1,1,0,0,1,0],
               [0,0,0,0,1,1],
               [0,0,1,0,1,0],
               [0,1,1,0,0,0],
               [0,1,1,0,0,0]]
Output: 11
Explanation:
One possible solution is [right, right, rotate clockwise, right, down, down, down, down, rotate counterclockwise, right, down].

Example 2:code

Input: grid = [[0,0,1,1,1,1],
               [0,0,0,0,1,1],
               [1,1,0,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,0]]
Output: 9

 

Constraints:htm

  • 2 <= n <= 100
  • 0 <= grid[i][j] <= 1
  • It is guaranteed that the snake starts at empty cells.

你還記得那條風靡全球的貪吃蛇嗎?blog

咱們在一個 n*n 的網格上構建了新的迷宮地圖,蛇的長度爲 2,也就是說它會佔去兩個單元格。蛇會從左上角((0, 0) 和 (0, 1))開始移動。咱們用 0 表示空單元格,用 1 表示障礙物。蛇須要移動到迷宮的右下角((n-1, n-2) 和 (n-1, n-1))。rem

每次移動,蛇能夠這樣走:

  • 若是沒有障礙,則向右移動一個單元格。並仍然保持身體的水平/豎直狀態。
  • 若是沒有障礙,則向下移動一個單元格。並仍然保持身體的水平/豎直狀態。
  • 若是它處於水平狀態而且其下面的兩個單元都是空的,就順時針旋轉 90 度。蛇從((r, c)(r, c+1))移動到 ((r, c)(r+1, c))。
  • 若是它處於豎直狀態而且其右面的兩個單元都是空的,就逆時針旋轉 90 度。蛇從((r, c)(r+1, c))移動到((r, c)(r, c+1))。

返回蛇抵達目的地所需的最少移動次數。

若是沒法到達目的地,請返回 -1

 

示例 1:

輸入:grid = [[0,0,0,0,0,1],
               [1,1,0,0,1,0],
               [0,0,0,0,1,1],
               [0,0,1,0,1,0],
               [0,1,1,0,0,0],
               [0,1,1,0,0,0]]
輸出:11
解釋:
一種可能的解決方案是 [右, 右, 順時針旋轉, 右, 下, 下, 下, 下, 逆時針旋轉, 右, 下]。

示例 2:

輸入:grid = [[0,0,1,1,1,1],
               [0,0,0,0,1,1],
               [1,1,0,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,0]]
輸出:9

 

提示:

  • 2 <= n <= 100
  • 0 <= grid[i][j] <= 1
  • 蛇保證從空單元格開始出發。

Runtime: 252 ms
Memory Usage: 21.2 MB
  1 class Solution {
  2     func minimumMoves(_ grid: [[Int]]) -> Int {
  3         let n:Int = grid.count
  4         var mem:[[[Bool]]] = [[[Bool]]](repeating: [[Bool]](repeating: [Bool](repeating: false, count: 2), count: n), count: n)
  5         var q:[Pos] = [Pos]()
  6         q.append(Pos(0, 0, 0, 0))
  7         while(!q.isEmpty)
  8         {
  9             let cur:Pos = q.removeFirst()
 10             if cur.s == 0 && cur.x == n - 1 && cur.y == n - 2
 11             {
 12                 return cur.step
 13             }
 14             for i in 0..<4
 15             {
 16                 if canMove(cur, i, grid, mem)
 17                 {
 18                     let next:Pos = move(cur, i)
 19                     mem[next.x][next.y][next.s] = true
 20                     q.append(next)
 21                 }
 22             }
 23         }
 24         return -1
 25     }
 26     
 27     func canMove(_ cur:Pos,_ s:Int,_ grid:[[Int]],_ mem:[[[Bool]]]) -> Bool
 28     {
 29         let n:Int = grid.count
 30         let x:Int = cur.x
 31         let y:Int = cur.y
 32         if s == 0
 33         {
 34             if cur.s == 0
 35             {
 36                 return y + 2 < n && !mem[x][y + 1][0] && grid[x][y + 2] != 1
 37             }
 38             else
 39             {
 40                 return y + 1 < n && !mem[x][y + 1][1] && grid[x][y + 1] != 1 && grid[x + 1][y + 1] != 1
 41             }
 42         }
 43         else if s == 1
 44         {
 45             if cur.s == 0
 46             {
 47                 return x + 1 < n && !mem[x + 1][y][0] && grid[x + 1][y] != 1 && grid[x + 1][y + 1] != 1
 48             }
 49             else
 50             {
 51                 return x + 2 < n && !mem[x + 1][y][1] && grid[x + 2][y] != 1
 52             }
 53         }
 54         else if s == 2
 55         {
 56             if cur.s != 0
 57             {
 58                 return false
 59             }
 60             return x + 1 < n && !mem[x][y][1] && grid[x + 1][y] != 1 && grid[x + 1][y + 1] != 1
 61         }
 62         else
 63         {
 64             if cur.s != 1
 65             {
 66                 return false
 67             }
 68             return y + 1 < n && !mem[x][y][0] && grid[x][y + 1] != 1 && grid[x + 1][y + 1] != 1
 69         }
 70     }
 71     
 72     func move(_ cur:Pos,_ s:Int) -> Pos
 73     {
 74         var x:Int = cur.x
 75         var y:Int = cur.y
 76         var pp = cur.s
 77         if s == 0
 78         {
 79             y += 1
 80         }
 81         else if s == 1
 82         {
 83             x += 1
 84         }
 85         else if s == 2
 86         {
 87             pp = 1
 88         }
 89         else
 90         {
 91             pp = 0
 92         }
 93          return Pos(x, y, pp, cur.step + 1)
 94     }
 95 }
 96 
 97 struct Pos
 98 {
 99     var x:Int = 0
100     var y:Int = 0
101     var s:Int = 0
102     var step:Int = 0
103     init(_ x:Int,_ y:Int,_ s:Int,_ step:Int)
104     {
105         self.x = x
106         self.y = y
107         self.s = s
108         self.step = step
109     }
110

236ms

 

 1 class Solution {
 2     func minimumMoves(_ grid: [[Int]]) -> Int {
 3         let rows = grid.count, cols = grid[0].count
 4         var queue = [(Int, Int, Int)]()
 5         queue.append((0, 0, 0))
 6 
 7         var dist = [[[Int]]](repeating: [[Int]](repeating: [Int](repeating: Int.max, count: 2), count: cols), count: rows)
 8 
 9         func valid(_ r: Int, _ c: Int) -> Bool {
10             return r >= 0 && r < rows && 0 <= c && c < cols
11         }
12 
13         func bfs_check(_ q: inout [(Int, Int, Int)], _ r: Int, _ c: Int, _ dir: Int, _ curDist: Int) {
14             if curDist < dist[r][c][dir] {
15                 dist[r][c][dir] = curDist;
16                 q.append((r, c, dir))
17             }
18         }
19         bfs_check(&queue, 0, 0, 0, 0)
20         while queue.count > 0 {
21             let (r, c, dir) = queue.removeFirst()
22             let curdist = dist[r][c][dir]
23             let r2 = dir == 0 ? r : r + 1
24             let c2 = dir == 0 ? c + 1 : c
25 
26             if valid(r, c + 1) && valid(r2, c2 + 1) && grid[r][c + 1] == 0 && grid[r2][c2 + 1] == 0 {
27                  bfs_check(&queue, r, c + 1, dir, curdist + 1)
28             }
29 
30             if valid(r + 1, c) && valid(r2 + 1, c2) && grid[r + 1][c] == 0 && grid[r2 + 1][c2] == 0 {
31                 bfs_check(&queue, r + 1, c, dir, curdist + 1)
32             }
33 
34             if dir == 0 {
35                 if valid(r + 1, c) && valid(r + 1, c + 1) && grid[r + 1][c] == 0 && grid[r + 1][c + 1] == 0 {
36                     bfs_check(&queue, r, c, 1, curdist + 1)
37                 }
38             } else {
39                 if valid(r, c + 1) && valid(r + 1, c + 1) && grid[r][c + 1] == 0 && grid[r + 1][c + 1] == 0 {
40                     bfs_check(&queue, r, c, 0, curdist + 1)
41                 }
42             }
43         }
44         let answer = dist[rows - 1][cols - 2][0]
45         return answer < Int.max ? answer : -1
46     }
47 }
相關文章
相關標籤/搜索