leetcode 773. 滑动谜题

@(labuladong的算法小抄)[BFS]

leetcode 773. 滑动谜题

题目描述

在这里插入图片描述

解题思路

参考:labuladong的算法小抄P310

class Solution {
    /* 2*3的原始数组中,每个元素的相邻元素的下标 */
    /* 例如neighbor[5]={2, 4}表示board中第6个数组的邻居元素分别是第3和第5个元素 */
    int[][] neighbor = new int[][]{
            {1, 3},
            {0, 2, 4},
            {1, 5},
            {0, 4},
            {1, 3, 5},
            {2, 4}
    };

    public int slidingPuzzle(int[][] board) {
        /* 将board展平为一维,存入start作为初始状态 */
        String start = "";
        /* 最终要凑出的目标 */
        String target = "123450";
        /* 初始化start */
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                start += (char) (board[i][j] + '0');
            }
        }

        /* BFS框架 */
        Queue<String> q = new LinkedList<>();
        Set<String> visited = new HashSet<>();
        q.offer(start);
        visited.add(start);
        /* 移动的步数 */
        int step = 0;

        while (!q.isEmpty()) {
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                String cur = q.poll();
                /* 到达终点,返回步数 */
                if (cur.equals(target)) {
                    return step;
                }
                /* 找到数字0的下标 */
                int zeroIdx = cur.indexOf('0');
                /* 遍历数字0的所有邻居的下标 */
                for (int idx : neighbor[zeroIdx]) {
	                /* 交换数字0和当前邻居元素的下标,生成新的拼图 */
                    String newBoard = exchangeIdxOfString(cur, zeroIdx, idx);
                    /* 防止重复访问 */
                    if (!visited.contains(newBoard)) {
                        q.offer(newBoard);
                        visited.add(newBoard);
                    }
                }
            }
            /* 遍历完当前层后,步数加1 */
            step++;
        }
        return -1;
    }

    /* 交换str中下标分别为src和dist的字符 */
    private String exchangeIdxOfString(String str, int src, int dist) {
        char[] tmpStr = str.toCharArray();

        char tmpCh = tmpStr[src];
        tmpStr[src] = tmpStr[dist];
        tmpStr[dist] = tmpCh;

        return new String(tmpStr);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值