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

}

总结

基于广度优先算法求解。

要点:

  • 将输入的多维数组转换为一维数组,计算指定位置的相邻节点。
  • 去重的方法。
相关推荐
Felven2 小时前
C. Isamatdin and His Magic Wand!
c语言·数据结构·算法
AndrewHZ2 小时前
【芯芯相印】什么是算法定点化?
pytorch·算法·芯片设计·模型量化·定点化·芯片算法·逻辑电路
数据科学小丫2 小时前
算法:线性回归
算法·回归·线性回归
剪一朵云爱着2 小时前
PAT 1131 Subway Map
算法·pat考试·图论
CoderYanger2 小时前
动态规划算法-子序列问题(数组中不连续的一段):30.最长数对链
java·算法·leetcode·动态规划·1024程序员节
啦哈拉哈2 小时前
【Python】知识点零碎学习1
数据结构·python·算法
多恩Stone2 小时前
【3DV 进阶-10】Trellis 中的表示 SLat 理解(1)
人工智能·python·算法·3d·aigc
京井2 小时前
从中序与后序遍历序列构造二叉树解题思路
c语言·算法
Han.miracle2 小时前
算法--003快乐数
数据结构·算法·快乐数