★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-ubbzhfqh-kt.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
On an alphabet board, we start at position (0, 0)
, corresponding to character board[0][0]
.git
Here, board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]
.github
We may make the following moves:微信
'U'
moves our position up one row, if the square exists;'D'
moves our position down one row, if the square exists;'L'
moves our position left one column, if the square exists;'R'
moves our position right one column, if the square exists;'!'
adds the character board[r][c]
at our current position (r, c)
to the answer.Return a sequence of moves that makes our answer equal to target
in the minimum number of moves. You may return any path that does so. app
Example 1:spa
Input: target = "leet" Output: "DDR!UURRR!!DDD!"
Example 2:code
Input: target = "code" Output: "RR!DDRR!UUL!R!"
Constraints:htm
1 <= target.length <= 100
target
consists only of English lowercase letters.咱們從一塊字母板上的位置 (0, 0)
出發,該座標對應的字符爲 board[0][0]
。blog
在本題裏,字母板爲board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]
.ci
咱們能夠按下面的指令規則行動:
'U'
意味着將咱們的位置上移一行;'D'
意味着將咱們的位置下移一行;'L'
意味着將咱們的位置左移一列;'R'
意味着將咱們的位置右移一列;'!'
會把在咱們當前位置 (r, c)
的字符 board[r][c]
添加到答案中。返回指令序列,用最小的行動次數讓答案和目標 target
相同。你能夠返回任何達成目標的路徑。
示例 1:
輸入:target = "leet" 輸出:"DDR!UURRR!!DDD!"
示例 2:
輸入:target = "code" 輸出:"RR!DDRR!UUL!R!"
提示:
1 <= target.length <= 100
target
僅含有小寫英文字母。1 class Solution { 2 func alphabetBoardPath(_ target: String) -> String { 3 var x:Int = 0 4 var y:Int = 0 5 var res:String = String() 6 let arrTarget:[Int] = Array(target).map{$0.ascii} 7 for ch in arrTarget 8 { 9 var x1:Int = (ch - 97) % 5 10 var y1:Int = (ch - 97) / 5 11 let str:String = String(repeating:"U",count:max(0, y - y1)) + String(repeating:"R",count:max(0, x1 - x)) + String(repeating:"L",count:max(0, x - x1)) + String(repeating:"D",count:max(0, y1 - y)) + "!" 12 res += str 13 x = x1 14 y = y1 15 } 16 return res 17 } 18 } 19 20 //Character擴展 21 extension Character 22 { 23 //Character轉ASCII整數值(定義小寫爲整數值) 24 var ascii: Int { 25 get { 26 return Int(self.unicodeScalars.first?.value ?? 0) 27 } 28 } 29 }
1 class Solution { 2 func alphabetBoardPath(_ target: String) -> String { 3 let board: [Character: (row: Int, col: Int)] = ["a": (0, 0), "b": (0, 1), "c": (0, 2), "d": (0, 3), "e": (0, 4), 4 "f": (1, 0), "g": (1, 1), "h": (1, 2), "i": (1, 3), "j": (1, 4), 5 "k": (2, 0), "l": (2, 1), "m": (2, 2), "n": (2, 3), "o": (2, 4), 6 "p": (3, 0), "q": (3, 1), "r": (3, 2), "s": (3, 3), "t": (3, 4), 7 "u": (4, 0), "v": (4, 1), "w": (4, 2), "x": (4, 3), "y": (4, 4), 8 "z": (5, 0) 9 ] 10 11 var prevChar: Character = "a" 12 var moves: String = "" 13 14 for eachChar in [Character](target) { 15 16 while eachChar != prevChar { 17 switch prevChar { 18 case "z": 19 moves += "U" 20 prevChar = "u" 21 continue 22 23 default: 24 let leftOrRight = board[eachChar]!.col - board[prevChar]!.col 25 let upOrDown = board[eachChar]!.row - board[prevChar]!.row 26 27 switch leftOrRight.signum() { // Move Left or Right 28 case -1: 29 moves += repeatElement("L", count: -leftOrRight) 30 case 1: 31 moves += repeatElement("R", count: leftOrRight) 32 default: 33 moves.append("") 34 } 35 36 switch upOrDown.signum() { // Then Move Up or Down 37 case -1: 38 moves += repeatElement("U", count: -upOrDown) 39 case 1: 40 moves += repeatElement("D", count: upOrDown) 41 default: 42 moves.append("") 43 } 44 } 45 prevChar = eachChar 46 } 47 moves += "!" 48 } 49 return moves 50 } 51 }
8ms
1 class Solution { 2 func position(of c: Character) -> (Int, Int) { 3 let av = Int(c.asciiValue! - 97) 4 return (av / 5, av % 5) 5 } 6 7 func path(from a: Character, to b: Character) -> String { 8 guard a != b else { 9 return "" 10 } 11 12 let posA = position(of: a) 13 let posB = position(of: b) 14 15 if a == "z" { 16 return String(repeating:"U", count:posA.0 - posB.0) + String(repeating:"R", count:posB.1 - posA.1) 17 } 18 if b == "z" { 19 return String(repeating:"L", count: posA.1 - posB.1) + String(repeating:"D", count:posB.0 - posA.0) 20 } 21 22 return String(repeating:posA.0 > posB.0 ? "U" : "D", count: abs(posA.0 - posB.0)) + String(repeating:posA.1 > posB.1 ? "L" : "R", count: abs(posA.1 - posB.1)) 23 } 24 25 func alphabetBoardPath(_ target: String) -> String { 26 var result = "" 27 var cc : Character = "a" 28 for c in target { 29 result += path(from: cc, to: c) + "!" 30 cc = c 31 } 32 return result 33 } 34 }
20ms
1 class Solution { 2 let board: [[Character]] = [Array("abcde"), Array("fghij"), Array("klmno"), Array("pqrst"), Array("uvwxy"), Array("z")] 3 let boardHash: [Character:Position] = 4 ["a": Position(0,0), "b": Position(0,1), "c": Position(0,2), "d": Position(0,3), "e": Position(0,4), 5 "f": Position(1,0), "g": Position(1,1), "h": Position(1,2), "i": Position(1,3), "j": Position(1,4), 6 "k": Position(2,0), "l": Position(2,1), "m": Position(2,2), "n": Position(2,3), "o": Position(2,4), 7 "p": Position(3,0), "q": Position(3,1), "r": Position(3,2), "s": Position(3,3), "t": Position(3,4), 8 "u": Position(4,0), "v": Position(4,1), "w": Position(4,2), "x": Position(4,3), "y": Position(4,4), 9 "z": Position(5,0)] 10 11 func alphabetBoardPath(_ target: String) -> String { 12 var hash = [Key:[Character]]() 13 return String(_alphabetBoardPath(Array(target), 0, Position(0,0), &hash)) 14 } 15 16 func _alphabetBoardPath(_ target: [Character], 17 _ i: Int, 18 _ position: Position, 19 _ hash: inout [Key:[Character]]) -> [Character] { 20 if i >= target.count { return [] } 21 22 let targetPosition = boardHash[target[i]]! 23 // let index = Key(i, position, visited) 24 // if let savedSolution = hash[index] { return savedSolution } 25 26 var solution: [Character] = [] 27 if targetPosition == position { 28 solution = ["!"] + _alphabetBoardPath(target, i+1, position, &hash) 29 } else { 30 let downP = Position(position.i+1, position.j) 31 let upP = Position(position.i-1, position.j) 32 let rightP = Position(position.i, position.j+1) 33 let leftP = Position(position.i, position.j-1) 34 35 if targetPosition.i == position.i { 36 if position.j < targetPosition.j { 37 solution = ["R"] + _alphabetBoardPath(target, i, rightP, &hash) 38 } else { 39 solution = ["L"] + _alphabetBoardPath(target, i, leftP, &hash) 40 } 41 } 42 else { 43 if position.i < targetPosition.i { 44 if downP.isValid(for: board) { 45 solution = ["D"] + _alphabetBoardPath(target, i, downP, &hash) 46 } else { 47 solution = ["L"] + _alphabetBoardPath(target, i, leftP, &hash) 48 } 49 50 } else { 51 solution = ["U"] + _alphabetBoardPath(target, i, upP, &hash) 52 } 53 } 54 } 55 56 // hash[index] = solution 57 return solution 58 } 59 } 60 61 struct Key: Hashable { 62 let i: Int 63 let position: Position 64 let visited: Set<Position> 65 66 init(_ i: Int, _ position: Position, _ visited: Set<Position>) { 67 self.i = i 68 self.position = position 69 self.visited = visited 70 } 71 } 72 73 struct Position: Hashable { 74 let i: Int 75 let j: Int 76 77 init(_ i: Int, _ j: Int) { 78 self.i = i 79 self.j = j 80 } 81 82 func isValid(for board: [[Character]]) -> Bool { 83 return i >= 0 && i < board.count && j >= 0 && j < board[i].count 84 } 85 }