773. Sliding Puzzle

这题看上去很难。
其实就是一常规题目,就是level order BFS呗。
follow up可能会是求path。
真的都是常规操作。
时间复杂度也很好分析,有多少种状态,每种做什么
下面看代码。

class Solution {
    int[][] OFFSETS;
    public int slidingPuzzle(int[][] board) {
        // 6 * 5 * 4 * 3 * 2 =  720 
        OFFSETS = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
        Queue queue = new LinkedList<>();
        int code = getCode(board);
        if (code == 123450) return 0;
        queue.offer(code);
        int level = 1;
        Set visited = new HashSet<>();
        visited.add(code);
        int[][] helper = new int[2][3];
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int state = queue.poll();
                for (int nextState : getNextState(state, helper)) {
                    if (visited.add(nextState)) {
                        if (nextState == 123450) return level;
                        queue.add(nextState);
                    }
                }
            }
            level++;
        }
        return -1;
    }
    private List getNextState(int state, int[][] helper) {
        int zeroRow = 0, zeroCol = 0;
        for (int row = 1; row >= 0; row --) {
            for (int col = 2; col >= 0; col--) {
                helper[row][col] = state % 10;
                if (helper[row][col] == 0) {
                    zeroRow = row;
                    zeroCol = col;
                }
                state /= 10;
            }
        }
        List ans = new ArrayList<>();
        for (int[] os : OFFSETS) {
            int nzr = zeroRow + os[0]; int nzc = zeroCol + os[1];
            if (nzr < 0 || nzc < 0 || nzr > 1 || nzc > 2) continue;
            swap(helper, zeroRow, zeroCol, nzr, nzc);
            ans.add(getCode(helper));
            swap(helper, zeroRow, zeroCol, nzr, nzc);
        }
        return ans;
    }
    
    private void swap(int[][] helper, int i, int j, int m, int n) {
        int tmp = helper[i][j];
        helper[i][j] = helper[m][n];
        helper[m][n] = tmp;
    }
    private int getCode(int[][] board) {
        int ans = 0;
        for (int[] row : board) {
            for (int n : row) {
                ans *= 10;
                ans += n;
            }
        }
        return ans;
    }
}

你可能感兴趣的:(773. Sliding Puzzle)