zoukankan      html  css  js  c++  java
  • [Swift]LeetCode864. 获取所有钥匙的最短路径 | Shortest Path to Get All Keys

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址: https://www.cnblogs.com/strengthen/p/10596616.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.

    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.

    For some 1 <= K <= 6, there is exactly one lowercase and one uppercase letter of the first Kletters 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:

    Input: ["@.a.#","###.#","b.A.B"]
    Output: 8
    

    Example 2:

    Input: ["@..aA","..B#.","....b"]
    Output: 6 

    Note:

    1. 1 <= grid.length <= 30
    2. 1 <= grid[0].length <= 30
    3. grid[i][j] contains only'.''#''@''a'-'f' and 'A'-'F'
    4. The number of keys is in [1, 6].  Each key has a different letter and opens exactly one lock.

    给定一个二维网格 grid。 "." 代表一个空房间, "#" 代表一堵墙, "@" 是起点,("a""b", ...)代表钥匙,("A""B", ...)代表锁。

    我们从起点开始出发,一次移动是指向四个基本方向之一行走一个单位空间。我们不能在网格外面行走,也无法穿过一堵墙。如果途经一个钥匙,我们就把它捡起来。除非我们手里有对应的钥匙,否则无法通过锁。

    假设 K 为钥匙/锁的个数,且满足 1 <= K <= 6,字母表中的前 K 个字母在网格中都有自己对应的一个小写和一个大写字母。换言之,每个锁有唯一对应的钥匙,每个钥匙也有唯一对应的锁。另外,代表钥匙和锁的字母互为大小写并按字母顺序排列。

    返回获取所有钥匙所需要的移动的最少次数。如果无法获取所有钥匙,返回 -1 。 

    示例 1:

    输入:["@.a.#","###.#","b.A.B"]
    输出:8
    

    示例 2:

    输入:["@..aA","..B#.","....b"]
    输出:6 

    提示:

    1. 1 <= grid.length <= 30
    2. 1 <= grid[0].length <= 30
    3. grid[i][j] 只含有 '.''#''@''a'-'f' 以及 'A'-'F'
    4. 钥匙的数目范围是 [1, 6],每个钥匙都对应一个不同的字母,正好打开一个对应的锁。

    Runtime: 532 ms
    Memory Usage: 20.5 MB
      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 }
  • 相关阅读:
    BiliBili, ACFun… And More!【递归算法】
    【VS2015】关于VS2015如何运行的问题
    【打死树莓派】-树莓派3代jessie+Opencv-解决安装不了libgtk2.0-dev包问题
    插入排序2.0
    【C++小白成长撸】--(续)单偶数N阶魔方矩阵
    【C++小白成长撸】--(续)双偶数N阶魔阵
    安装 python-opencv
    二叉树打印
    Kotlin接口
    Kotlin 继承
  • 原文地址:https://www.cnblogs.com/strengthen/p/10596616.html
Copyright © 2011-2022 走看看