/*
难度:困难
在一个2x3的板上有5块砖瓦,用数字1~5来表示,以及一块空缺用0表示。
一次移动定义为选择0与一个相邻的数字进行交换。
最终当板上的结果是 [[1,2,3], [4,5,0]]时,谜板被揭开。
给出一个初始状态,返回最少可以通过多少次移动揭开谜板,如果解不开,则返回-1
*/
class Node773 {
var code: Int
var connected = [Int]() //与本节点有连线的其他节点
init(code: Int) {
self.code = code
}
static let nodesMap: [Int:Node773] = {
var tempMap = [Int:Node773]()
for a in 0..<6 {
let sa = a * 100000
for b in 0..<6 {
if b == a {
continue
}
let sb = b * 10000
for c in 0..<6 {
if c == a || c == b {
continue
}
let sc = c * 1000
for d in 0..<6 {
if d == c || d == b || c == a {
continue
}
let sd = d * 100
for e in 0..<6 {
if e == d || e == c || e == b || e == a {
continue
}
let se = e * 10
for f in 0..<6 {
if f == e || f == d || f == c || f == b || f == a {
continue
}
let code = sa + sb + sc + sd + se + f
let node = Node773(code: code)
//相连的节点
if a == 0 {
node.connected.append(code - sb + b*100000)
node.connected.append(code - sd + d*100000)
} else if b == 0 {
node.connected.append(code - sa + a*10000)
node.connected.append(code - sc + c*10000)
node.connected.append(code - se + e*10000) //1 和 4比四角要多一个
} else if c == 0 {
node.connected.append(code - sb + b*1000)
node.connected.append(code - f + f*1000)
} else if d == 0 {
node.connected.append(code - sa + a*100)
node.connected.append(code - se + e*100)
} else if e == 0 {
node.connected.append(code - sd + d*10)
node.connected.append(code - f + f*10)
node.connected.append(code - sb + b*10) //1 和 4比四角要多一个
} else if f == 0 {
node.connected.append(code - sc + c)
node.connected.append(code - se + e)
}
tempMap[code] = node
}
}
}
}
}
}
return tempMap
}()
}
extension Daily {
static func test_leetcode773() {
// let board = [[1,2,3], [4,0,5]]
// let board = [[1,2,3], [5,4,0]]
// let board = [[4,1,2],[5,0,3]]
let board = [[3,2,4],[1,5,0]]
let res = Daily.leetcode773(board)
print("结果 \(res)")
}
static func leetcode773(_ board: [[Int]]) -> Int {
let target = 123450
let startCode = board[0][0]*100000 + board[0][1]*10000 + board[0][2]*1000 +
board[1][0]*100 + board[1][1]*10 + board[1][2]
let nodesMap = Node773.nodesMap
let startNode: Node773! = nodesMap[startCode]
if startNode == nil {
return -1
}
var map = [Int:Int]()
for item in nodesMap.keys {
if item != startCode {
map[item] = 1000
}
else {
map[item] = 0
}
}
var finished = [Int:Int]()
var todo = [Int]()
todo.append(contentsOf: startNode.connected)
for item in startNode.connected {
map[item] = 1
}
var idx = 0
while todo.count > 0 && idx < todo.count {
let pcode = todo[idx]
if pcode == target {
break
}
let pnode = nodesMap[pcode]!
for item in pnode.connected {
let done = finished[item]
if done == nil {
todo.append(item)
finished[item] = 1
}
if map[item]! > map[pcode]! + 1 {
map[item] = map[pcode]! + 1
}
}
finished[pcode] = 2
idx += 1
}
return map[target]! == 1000 ? -1 : map[target]!
}
}
【LeetCode 773】滑动谜题
最新推荐文章于 2022-08-03 11:15:06 发布