八数码问题dfs

八数码问题dfs_第1张图片 




import java.util.*;

public class Main{
    static String end = "12345678x";
    public static void swap(char[] arr,int x,int y){
        char temp = arr[x];
        arr[x] = arr[y];
        arr[y] = temp;
    }

    public static int bfs(String start){
        //key:String 存放12345678x这种格式的字符
        //value:int 存放start - key 这个状态需要多少步
        //最终的map.get(end)就是答案
        Map map = new HashMap<>();
        //里面放12345678x这种格式的字符
        Queue q = new LinkedList<>();

        //开始宽搜
        //先把头节点放入队列
        q.offer(start);
        //初始化头节点
        //根据上面的定义 start -> start所需的步数为0
        map.put(start,0);

        //用将字符串转成3 * 3的数组,用偏移量来表示哪些点可以走(可以交换)(可以走到x这个位置)
        int[] dx = {-1,0,1,0}, dy = {0,1,0,-1};

        while (!q.isEmpty()){
            //只要队列不空,就把队头拿出来,并把队头可以扩展的点放入
            String t = q.poll();

            if (t.equals(end)) return map.get(t);

            //然后对t做文章(扩展)
            //t是12345678x格式的字符,要找到x的下标,对应到3 * 3的矩阵,去找可以上下左右扩展的点
            int k = t.indexOf('x');

            int x = k / 3;
            int y = k % 3;

            for (int i = 0; i < 4; i++) {
                int a = x + dx[i];
                int b = y + dy[i];
                //将满足条件的点(没被用过且再矩阵內部)加入队列,更新map
                if (a >= 0 && b >= 0 && a < 3 && b < 3){
                    //将满足条件的点()加入队列,更新map
                    //拿到下一个点的状态,看看这个状态是否已经被遍历过了
                    char[] arr = t.toCharArray();
                    swap(arr,k,a * 3 + b);
                    //此时的arr数组就是下一个可以走的点
                    //将arr转成字符串
                    String str = new String(arr);
                    if (map.get(str) == null){
                        //该点第一次遍历,更新map里的点并且把它放入队列
                        map.put(str,map.get(t) + 1);
                        q.offer(str);
                    }
                    //因为这里操作的是arr数组,并没有操作t,恢复现场可有可无
                }
            }
        }
        return -1;
    }

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String start = "";
        for (int i = 0; i < 9; i++) {
            String s = sc.next();
            start += s;
        }
        System.out.println(bfs(start));
    }
}

你可能感兴趣的:(算法,java,算法,数据结构,哈希算法)