★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(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 }