★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-bualtovw-me.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
We are given a 2-dimensional grid
. "."
is an empty cell, "#"
is a wall, "@"
is the starting point, ("a"
, "b"
, ...) are keys, and ("A"
, "B"
, ...) are locks.git
We start at the starting point, and one move consists of walking one space in one of the 4 cardinal directions. We cannot walk outside the grid, or walk into a wall. If we walk over a key, we pick it up. We can't walk over a lock unless we have the corresponding key.github
For some 1 <= K <= 6, there is exactly one lowercase and one uppercase letter of the first K
letters of the English alphabet in the grid. This means that there is exactly one key for each lock, and one lock for each key; and also that the letters used to represent the keys and locks were chosen in the same order as the English alphabet.數組
Return the lowest number of moves to acquire all keys. If it's impossible, return -1
. 微信
Example 1:app
Input: ["@.a.#","###.#","b.A.B"]
Output: 8
Example 2:less
Input: ["@..aA","..B#.","....b"]
Output: 6
Note:ide
1 <= grid.length <= 30
1 <= grid[0].length <= 30
grid[i][j]
contains only'.'
, '#'
, '@'
, 'a'-
'f
'
and 'A'-'F'
[1, 6]
. Each key has a different letter and opens exactly one lock.給定一個二維網格 grid
。 "."
表明一個空房間, "#"
表明一堵牆, "@"
是起點,("a"
, "b"
, ...)表明鑰匙,("A"
, "B"
, ...)表明鎖。函數
咱們從起點開始出發,一次移動是指向四個基本方向之一行走一個單位空間。咱們不能在網格外面行走,也沒法穿過一堵牆。若是途經一個鑰匙,咱們就把它撿起來。除非咱們手裏有對應的鑰匙,不然沒法經過鎖。post
假設 K 爲鑰匙/鎖的個數,且知足 1 <= K <= 6
,字母表中的前 K 個字母在網格中都有本身對應的一個小寫和一個大寫字母。換言之,每一個鎖有惟一對應的鑰匙,每一個鑰匙也有惟一對應的鎖。另外,表明鑰匙和鎖的字母互爲大小寫並按字母順序排列。
返回獲取全部鑰匙所須要的移動的最少次數。若是沒法獲取全部鑰匙,返回 -1
。
示例 1:
輸入:["@.a.#","###.#","b.A.B"] 輸出:8
示例 2:
輸入:["@..aA","..B#.","....b"] 輸出:6
提示:
1 <= grid.length <= 30
1 <= grid[0].length <= 30
grid[i][j]
只含有 '.'
, '#'
, '@'
, 'a'-
'f
'
以及 'A'-'F'
[1, 6]
,每一個鑰匙都對應一個不一樣的字母,正好打開一個對應的鎖。1 class Solution { 2 func shortestPathAllKeys(_ grid: [String]) -> Int { 3 var x:Int = -1 4 var y:Int = -1 5 var m:Int = grid.count 6 var n:Int = grid[0].count 7 var maxNum:Int = -1 8 for i in 0..<m 9 { 10 for j in 0..<n 11 { 12 var c:Character = grid[i][j] 13 if c == "@" 14 { 15 x = i 16 y = j 17 } 18 if c >= "a" && c <= "f" 19 { 20 maxNum = max(c.ascii - 97 + 1, maxNum) 21 } 22 } 23 } 24 var start:State = State(0, x, y) 25 var q:[State] = [State]() 26 var visited:Set<String> = Set<String>() 27 visited.insert(String(0) + " " + String(x) + " " + String(y)) 28 q.append(start) 29 var dirs:[[Int]] = [[0, 1],[1, 0],[0, -1],[-1, 0]] 30 var step:Int = 0 31 while (!q.isEmpty) 32 { 33 var size:Int = q.count 34 while(size-- > 0) 35 { 36 var cur:State = q.removeFirst() 37 if cur.keys == ((1 << maxNum) - 1) 38 { 39 return step 40 } 41 for dir in dirs 42 { 43 var i:Int = cur.i + dir[0] 44 var j:Int = cur.j + dir[1] 45 var keys:Int = cur.keys 46 if i >= 0 && i < m && j >= 0 && j < n 47 { 48 var c:Character = grid[i][j] 49 if c == "#" 50 { 51 continue 52 } 53 if c >= "a" && c <= "f" 54 { 55 keys |= 1 << (c.ascii - 97) 56 } 57 if c >= "A" && c <= "F" && ((keys >> (c.ascii - 65)) & 1) == 0 58 { 59 continue 60 } 61 var str:String = String(keys) + " " + String(i) + " " + String(j) 62 if !visited.contains(str) 63 { 64 visited.insert(str) 65 q.append(State(keys, i, j)) 66 } 67 } 68 } 69 } 70 step += 1 71 } 72 return -1 73 } 74 } 75 76 class State 77 { 78 var keys:Int 79 var i:Int 80 var j:Int 81 init(_ keys:Int,_ i:Int,_ j:Int) 82 { 83 self.keys = keys 84 self.i = i 85 self.j = j 86 } 87 } 88 89 //String擴展 90 extension String { 91 //subscript函數能夠檢索數組中的值 92 //直接按照索引方式截取指定索引的字符 93 subscript (_ i: Int) -> Character { 94 //讀取字符 95 get {return self[index(startIndex, offsetBy: i)]} 96 } 97 } 98 99 //Character擴展 100 extension Character 101 { 102 //Character轉ASCII整數值(定義小寫爲整數值) 103 var ascii: Int { 104 get { 105 return Int(self.unicodeScalars.first?.value ?? 0) 106 } 107 } 108 } 109 110 /*擴展Int類,實現自增++、自減--運算符*/ 111 extension Int{ 112 //後綴--:先執行表達式後再自減 113 static postfix func --(num:inout Int) -> Int { 114 //輸入輸出參數num 115 let temp = num 116 //num減1 117 num -= 1 118 //返回減1前的數值 119 return temp 120 } 121 }