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);
        }
    }

}

总结

基于广度优先算法求解。

要点:

  • 将输入的多维数组转换为一维数组,计算指定位置的相邻节点。
  • 去重的方法。
相关推荐
信奥卷王9 小时前
[GESP202609 六级] 分树规划
算法
夏幻灵9 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
徐小黑ACG11 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
Navigator_Z11 小时前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
北极有牛12 小时前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记12 小时前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
浮链序12 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室12 小时前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
圣保罗的大教堂13 小时前
leetcode 301. 删除无效的括号 困难
leetcode