import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
/**
* 773. 滑动谜题
*
* BFS
* 注意点:
* 本题中,搜索的状态 status 是一个 2×3 的二维数组,在很多语言中,
* 我们无法将数组直接放入哈希表中(Set中存放 int[] 无法去重,必须转换),可行的解决方案有两种:
* 自行实现数组的哈希函数;
* 将数组转换成语言中可以直接进行哈希的类型。
*
* 时间复杂度:O((mn)!mn)
* 空间复杂度:O((mn)!mn)
*/
public class Solution773 {
private static final int[] STRING_END = {1,2,3,4,5,0};
private static final int[][] DIRECTION_ARRAY = {{1, 3}, {0, 2, 4}, {1, 5}, {0, 4}, {1, 3, 5}, {2, 4}};
public int slidingPuzzle(int[][] board) {
int[] res = new int[6];
int t = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
res[t++] = board[i][j];
}
}
if (Arrays.equals(res, STRING_END)) {
return 0;
}
int step = 0;
Queue<int[]> queue = new LinkedList<>();
queue.offer(res);
Set<String> seen = new HashSet<>();
seen.add(Arrays.toString(res));
while (!queue.isEmpty()) {
++step;
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] state = queue.poll();
for (int[] nextStatus : get(state)) {
if (!seen.contains(Arrays.toString(nextStatus))) {
if (Arrays.equals(nextStatus, STRING_END)) {
return step;
}
queue.offer(nextStatus);
seen.add(Arrays.toString(nextStatus));
}
}
}
// 测试,最多不会超过21(打表测试)
if (step > 21) {
break;
}
}
return -1;
}
private List<int[]> get(int[] status) {
List<int[]> ret = new ArrayList<>();
int x = findZero(status);
for (int y : DIRECTION_ARRAY[x]) {
swap(status, x, y);
int[] temp = Arrays.copyOf(status, 6);
ret.add(temp);
swap(status, x, y);
}
return ret;
}
private int findZero(int[] status){
int step = 0;
for (int a : status) {
if (a == 0) {
return step;
}
step++;
}
return -1;
}
private void swap(int[] array, int x, int y) {
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
public static void main(String args[]){
Solution773 solution773 = new Solution773();
System.out.println(solution773.slidingPuzzle(new int[][]{{1,2,3},{5,4,0}}));
}
}
LeetCode -- 773. 滑动谜题
最新推荐文章于 2021-09-02 03:21:05 发布