LeetCode第773题 - 滑动谜题

题目

解答

java 复制代码
class Solution {

    static int V_RIGHT = 1;

    static int V_LEFT = 2;

    static int H_UP = 3;

    static int H_DOWN = 4;

    LinkedList<int[]> queue = new LinkedList<>();

    Set<Integer> visited = new HashSet<>();

    public int slidingPuzzle(int[][] board) {
        int m = board.length;
        int n = board[0].length;

        int[] target = new int[] {1, 2, 3, 4, 5, 0};

        int step = 0;

        int[] init = new int[m * n];
        for (int i = 0, pos = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j, ++pos) {
                init[pos] = board[i][j];
            }
        }

        queue.add(init);
        visited.add(hash(init));

        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; ++i) {
                int[] status = queue.removeFirst();
                if (equals(status, target)) {
                    return step;
                }

                int index = 0;
                for (int j = 0; j < status.length; ++j) {
                    if (status[j] == 0) {
                        index = j;
                        break;
                    }
                }

                moveV(status, n, index, V_LEFT);
                moveV(status, n, index, V_RIGHT);
                moveH(status, n, index, H_UP);
                moveH(status, n, index, H_DOWN);
            }

            ++step;
        }

        return -1;
    }

    int hash(int[] status) {
        int hashCode = 11;
        for (int i = 0; i < status.length; ++i) {
            hashCode = hashCode * 7 + status[i];
        }
        return hashCode;
    }

    boolean equals(int[] status, int[] target) {
        for (int i = 0; i < status.length; ++i) {
            if (status[i] != target[i]) {
                return false;
            }
        }

        return true;
    }

    void moveV(int[] status, int column, int index, int flag) {
        int[] newStatus = Arrays.copyOf(status, status.length);
        // 和右边交换。
        if (flag == V_RIGHT) {

            if (index % column + 1 < column) {
                newStatus[index] = newStatus[index + 1];
                newStatus[index + 1] = 0;
            }
        }
        // 和左边交换
        else if (flag == V_LEFT) {
            if (index % column - 1 >= 0) {
                newStatus[index] = newStatus[index - 1];
                newStatus[index - 1] = 0;
            }
        }

        int hashCode = hash(newStatus);

        if (visited.add(hashCode)) {
            queue.add(newStatus);
        }
    }

    void moveH(int[] status, int column, int index, int flag) {
        int[] newStatus = Arrays.copyOf(status, status.length);
        if (flag == H_UP) {
            if (index - column >= 0) {
                newStatus[index] = newStatus[index - column];
                newStatus[index - column] = 0;
            }
        } else if (flag == H_DOWN) {
            if (index + column < status.length) {
                newStatus[index] = newStatus[index + column];
                newStatus[index + column] = 0;
            }
        }

        int hashCode = hash(newStatus);

        if (visited.add(hashCode)) {
            queue.add(newStatus);
        }
    }

}

总结

基于广度优先算法求解。

要点:

  • 将输入的多维数组转换为一维数组,计算指定位置的相邻节点。
  • 去重的方法。
相关推荐
裕晟资质规划12 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法
en.en..13 小时前
C语言 标准输入 / 输出缓冲区
算法
吃好睡好便好15 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学习星球15 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
靠沿16 小时前
贪心算法专题(二)
算法·贪心算法
猎头南楼17 小时前
具身智能模型部署方向的能力要求与技术栈梳理
人工智能·深度学习·算法
啥都想学点的研究生18 小时前
一篇文章讲清楚:线性回归问题的求解——正规方程法
算法·机器学习·线性回归
青少儿编程课堂18 小时前
树状数组精讲:逆序对计数与离散化(附双语言解法)
算法·树状数组·离散化·信息学奥赛·逆序对
血小板要健康18 小时前
网格 dfs 与 FloodFill:从岛屿、区域到搜索路径
笔记·算法·leetcode·深度优先
VALENIAN瓦伦尼安教学设备19 小时前
设备状态检测振动分析实训台案例分析
大数据·数据库·人工智能·嵌入式硬件·算法