问题描述
在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.
最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
给出一个谜板的初始状态 board ,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
输入:board = [[1,2,3],[4,0,5]] 输出:1 解释:交换 0 和 5 ,1 步完成输入:board = [[1,2,3],[5,4,0]] 输出:-1 解释:没有办法完成谜板提示:
board.length == 2
board[i].length == 3
0 <= board[i][j] <= 5
board[i][j] 中每个值都 不同来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sliding-puzzle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Java
class Solution {
//0只能和相邻的数字进行交换
int[][] neighbors = {
{1,3},
{0,2,4},
{1,5},
{0,4},
{1,3,5},
{2,4}
};
public int slidingPuzzle(int[][] board) {
//用字符串拼接这个矩阵
StringBuilder sb = new StringBuilder();
for(int i = 0;i < 2;i++){
for(int j = 0;j < 3;j++){
sb.append(board[i][j]);
}
}
String original = sb.toString();
if("123450".equals(original)) return 0;
Queue<String> queue = new LinkedList<>();
queue.offer(original);
Set<String> set = new HashSet<>();
set.add(original);
int step = 0;
while(!queue.isEmpty()){
step++;
int size = queue.size();
for(int i = 0;i < size;i++){
String status = queue.poll();
for(String s : get(status)){
if(!set.contains(s)){
if("123450".equals(s)) return step;
queue.offer(s);
set.add(s);
}
}
}
}
return -1;
}
public List<String> get(String s){
List<String> ans = new ArrayList<>();
char[] arr = s.toCharArray();
int x = s.indexOf('0');
for(int y : neighbors[x]){
swap(arr,x,y);
ans.add(new String(arr));
swap(arr,x,y);
}
return ans;
}
public void swap(char[] arr,int x,int y){
char c = arr[x];
arr[x] = arr[y];
arr[y] = c;
}
}