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

}

总结

基于广度优先算法求解。

要点:

  • 将输入的多维数组转换为一维数组,计算指定位置的相邻节点。
  • 去重的方法。
相关推荐
tod11317 小时前
从零手写一个面试级 C++ vector:内存模型、拷贝语义与扩容策略全解析
c++·面试·职场和发展·stl·vector
囊中之锥.17 小时前
机器学习算法详解:DBSCAN 聚类原理、实现流程与优缺点分析
算法·机器学习·聚类
AlenTech17 小时前
152. 乘积最大子数组 - 力扣(LeetCode)
算法·leetcode·职场和发展
Piar1231sdafa18 小时前
基于yolo13-C3k2-RVB的洗手步骤识别与检测系统实现_1
人工智能·算法·目标跟踪
a程序小傲18 小时前
中国邮政Java面试被问:Netty的FastThreadLocal优化原理
java·服务器·开发语言·面试·职场和发展·github·哈希算法
做科研的周师兄18 小时前
【MATLAB 实战】|多波段栅格数据提取部分波段均值——批量处理(NoData 修正 + 地理信息保真)_后附完整代码
前端·算法·机器学习·matlab·均值算法·分类·数据挖掘
天赐学c语言18 小时前
1.18 - 滑动窗口最大值 && 子类的指针转换为父类的指针,指针的值是否会改变
数据结构·c++·算法·leecode
甄心爱学习18 小时前
KMP算法(小白理解)
开发语言·python·算法
wen__xvn19 小时前
牛客周赛 Round 127
算法
大锦终19 小时前
dfs解决FloodFill 算法
c++·算法·深度优先