在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示.
一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换.
最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
给出一个谜板的初始状态,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
示例:
输入:board = [[1,2,3],[4,0,5]]
输出:1
解释:交换 0 和 5 ,1 步完成
输入:board = [[1,2,3],[5,4,0]]
输出:-1
解释:没有办法完成谜板
输入:board = [[4,1,2],[5,0,3]]
输出:5
解释:
最少完成谜板的最少移动次数是 5 ,
一种移动路径:
尚未移动: [[4,1,2],[5,0,3]]
移动 1 次: [[4,1,2],[0,5,3]]
移动 2 次: [[0,1,2],[4,5,3]]
移动 3 次: [[1,0,2],[4,5,3]]
移动 4 次: [[1,2,0],[4,5,3]]
移动 5 次: [[1,2,3],[4,5,0]]
输入:board = [[3,2,4],[1,5,0]]
输出:14
提示:
board 是一个如上所述的 2 x 3 的数组.
board[i][j] 是一个 [0, 1, 2, 3, 4, 5] 的排列.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sliding-puzzle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:和昨天的有点像,磕磕绊绊的写出来了,但是很丑,抄了一边三叶姐的题解,然后写了注释加深了一下理解。
class Solution {
class Node{
String str;
int x,y;
Node(String _str,int _x,int _y){
str = _str; x = _x; y = _y;
}
}
int n=2,m=3;
String s,e;
int x,y;
public int slidingPuzzle(int[][] board) {
s = "";
e = "123450";
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
s += board[i][j];
if(board[i][j]==0){x=i;y=j;}
}
int ans = bfs();
return ans;
}
//四个方向
int[][] dirs = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};
int bfs(){
Deque<Node> d = new ArrayDeque<>();
Map<String,Integer> map = new HashMap<>();
Node root = new Node(s,x,y);
d.addLast(root);
map.put(s,0);
//如果d不为空
while(!d.isEmpty()){
Node poll = d.pollFirst();
//走了几步
int step = map.get(poll.str);
//如果得到结果了,就返回步数
if(poll.str.equals(e)) return step;
int dx = poll.x;
int dy = poll.y;
//走四个方向
for(int[] di: dirs){
//下一步之后的x,y
int nx = dx+di[0];
int ny = dy+di[1];
//如果越界那就continue
if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
//变更后的str
String nStr = update(poll.str,dx,dy,nx,ny);
//如果已经有了那就continue
if(map.containsKey(nStr)) continue;
Node next = new Node(nStr,nx,ny);
//添加新的
d.addLast(next);
map.put(nStr,step+1);
}
}
return -1;
}
String update(String cur, int i, int j, int p, int q) {
char[] cs = cur.toCharArray();
//交换两个的值,他这里写的有点花里胡哨,哈哈哈哈
char tmp = cs[i * m + j];
cs[i * m + j] = cs[p * m + q];
cs[p * m + q] = tmp;
return String.valueOf(cs);
}
}