题目如下:

On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0.
A move consists of choosing 0 and a 4-directionally adjacent number and swapping it.
The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]].
Given a puzzle board, return the least number of moves required so that the state of the board is solved.
If it is impossible for the state of the board to be solved, return -1. Examples:
Input: board = [[1,2,3],[4,0,5]]
Output: 1
Explanation: Swap the 0 and the 5 in one move.


Input: board = [[1,2,3],[5,4,0]]
Output: -1
Explanation: No number of moves will make the board solved.


Input: board = [[4,1,2],[5,0,3]]
Output: 5
Explanation: 5 is the smallest number of moves that solves the board.
An example path:
After move 0: [[4,1,2],[5,0,3]]
After move 1: [[4,1,2],[0,5,3]]
After move 2: [[0,1,2],[4,5,3]]
After move 3: [[1,0,2],[4,5,3]]
After move 4: [[1,2,0],[4,5,3]]
After move 5: [[1,2,3],[4,5,0]]
Input: board = [[3,2,4],[1,5,0]]
Output: 14


Note:
board will be a 2 x 3 array as described above.
board[i][j] will be a permutation of [0, 1, 2, 3, 4, 5].

解题思路:对于这个题目,我也没想到特别好的方法。不过既然题目约定了是一个2*3的board,那么基本上就不用考虑性能问题了,所以可以简单粗暴的用穷举法。怎么穷举呢,最简单的是倒推,因为如果题目有解的话最终的结果一定是 [[1,2,3],[4,5,0]],我们可以用这个状态作为起点,计算出多少次移动能移动到和输入board一样的状态。因为只能移动0,而且只有上下左右四种移动方向,这个就是一个很典型的广度遍历的场景,注意每次移动后都要记录当前的状态,也要记录到达这个状态需要移动的次数,用来和board比较,如果一致就不需要再继续移动了。最后,当然也可以事先把所有能移动到达的状态先计算出来并进行缓存,之后就直接和board进行比较就行了。

完整代码:

import copy
class Solution(object):
def slidingPuzzle(self, board):
"""
:type board: List[List[int]]
:rtype: int
"""
pass
def toString(self,b):
s = ''
for i in b:
for j in i:
s += str(j)
return s
def getIndex(self,b):
for i in range(len(b)):
for j in range(len(b[0])):
if b[i][j] == 0:
return [i,j]
return []
def swap(self,b,x1,y1,x2,y2):
t = b[x1][y1]
b[x1][y1] = b[x2][y2]
b[x2][y2] = t
def slidingPuzzle(self, board):
des = [[1,2,3],[4,5,0]]
#print self.toString(board)
res = []
res.append(self.toString(des))
stack = []
stack.append([des,0]) while len(stack) > 0:
e = stack[0]
if e[0] == board:
return e[1]
#break
del stack[0] #print 'step',e[1]
#print e[0][0]
#print e[0][1]
#print '**********' inx = self.getIndex(e[0])
#up:
if inx[0] - 1 == 0:
bup = copy.deepcopy(e[0])
self.swap(bup, inx[0], inx[1], inx[0] -1,inx[1])
if self.toString(bup) not in res:
res.append(self.toString(bup))
stack.append([bup,e[1]+1])
#down
if inx[0] + 1 == 1:
bdown = copy.deepcopy(e[0])
self.swap(bdown, inx[0], inx[1], inx[0] + 1,inx[1])
if self.toString(bdown) not in res:
res.append(self.toString(bdown))
stack.append([bdown,e[1]+1])
#left
if inx[1] - 1 >= 0:
bleft = copy.deepcopy(e[0])
self.swap(bleft, inx[0], inx[1], inx[0],inx[1]-1)
if self.toString(bleft) not in res:
res.append(self.toString(bleft))
stack.append([bleft,e[1]+1])
#right
if inx[1] + 1 <= 2:
bright = copy.deepcopy(e[0])
self.swap(bright, inx[0], inx[1], inx[0] ,inx[1]+1)
if self.toString(bright) not in res:
res.append(self.toString(bright))
stack.append([bright,e[1]+1])
return -1

【leetcode】Sliding Puzzle的更多相关文章

  1. 【LeetCode】BFS(共43题)

    [101]Symmetric Tree 判断一棵树是不是对称. 题解:直接递归判断了,感觉和bfs没有什么强联系,当然如果你一定要用queue改写的话,勉强也能算bfs. // 这个题目的重点是 比较 ...

  2. 【LeetCode】堆 heap(共31题)

    链接:https://leetcode.com/tag/heap/ [23] Merge k Sorted Lists [215] Kth Largest Element in an Array (无 ...

  3. 【LeetCode】Minimum Depth of Binary Tree 二叉树的最小深度 java

    [LeetCode]Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum dept ...

  4. 【Leetcode】Pascal&#39;s Triangle II

    Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3 ...

  5. 53. Maximum Subarray【leetcode】

    53. Maximum Subarray[leetcode] Find the contiguous subarray within an array (containing at least one ...

  6. 27. Remove Element【leetcode】

    27. Remove Element[leetcode] Given an array and a value, remove all instances of that value in place ...

  7. 【刷题】【LeetCode】007-整数反转-easy

    [刷题][LeetCode]总 用动画的形式呈现解LeetCode题目的思路 参考链接-空 007-整数反转 方法: 弹出和推入数字 & 溢出前进行检查 思路: 我们可以一次构建反转整数的一位 ...

  8. 【刷题】【LeetCode】000-十大经典排序算法

    [刷题][LeetCode]总 用动画的形式呈现解LeetCode题目的思路 参考链接 000-十大经典排序算法

  9. 【leetcode】893. Groups of Special-Equivalent Strings

    Algorithm [leetcode]893. Groups of Special-Equivalent Strings https://leetcode.com/problems/groups-o ...

随机推荐

  1. python基础语法之字符串

    1 字符串中*的使用 *可以使字符串重复n次 print('hello world ' * 2) # hello world hello world 2 索引获取字符串的字符元素 print('hel ...

  2. 去掉有序数组中的重复元素 c/c++

    去掉有序数组中的重复元素: int RemoveDuplates(int A[], int nCnt) { ; ; , j = ; i < nCnt && j < nCnt ...

  3. [ASP.NET] 数据绑定以及Container.DataItem的具体分析 [转]

    灵活的运用数据绑定操作        绑定到简单属性:<%#UserName%>        绑定到集合:<asp:ListBox id="ListBox1" ...

  4. Atomic实现原子性源码分析:CAS(比较并交换)、Unsafe类

    1.CAS: 比较并交换(Compare And Swap),是Unsafe类中的一条CPU系统原语,原语的执行必须是连续的,在执行过程中不允许被中断,即CAS是一条CPU的原子指令,不会造成数据不一 ...

  5. 小记---------kafka理论及命令行操作

    kafka-0.10.1.X版本之前: auto.offset.reset 的值为smallest,和,largest.(offest保存在zk中)   kafka-0.10.1.X版本之后: aut ...

  6. numpy使用数组进行数据处理

    numpy使用数组进行数据处理 meshgrid函数 理解: 二维坐标系中,X轴可以取三个值1,2,3, Y轴可以取三个值7,8, 请问可以获得多少个点的坐标? 显而易见是6个: (1,7)(2,7) ...

  7. POJ - 1287 Networking (最小生成树&并查集

    You are assigned to design network connections between certain points in a wide area. You are given ...

  8. phpstorm 不能选择 php language level

    最近需要更改phpstorm中的php language level发现更改不了 解决方法是在PHP 下面的Composer中勾选了同步 composer php版本的原因 取消勾选,点击应用就可以了

  9. Thymeleaf模板中变量报红

    在上顶部添加 <!--suppress ThymeleafVariablesResolveInspection --> 或者 <!--suppress ALL --> 都可以解 ...

  10. git diff 命令用法

    理解git diff的前提,首先要理解git中工作区,暂存区,本地版本库的概念,如果头脑中有这些概念,接着往下读. git diff test.c 用来查看工作区和暂存区中test.c文件的区别. g ...