Sliding Puzzle

On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0.

A move consists of choosing 0 and a 4-directionally adjacent number and swapping it.

The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]].

Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -1.

Examples:

Input: board = [[1,2,3],[4,0,5]]
Output: 1
Explanation: Swap the 0 and the 5 in one move.
Input: board = [[1,2,3],[5,4,0]]
Output: -1
Explanation: No number of moves will make the board solved.

思路:这题不难,就是个BFS,但是triky的地方就是要把board转换成string,然后0,怎么挪动,用下面二维数组;

when zero is in position:0 it can go to cell {1,3}, position:1 it can go {0,2,4} and so on, also when i mean position i'm talking about the index of zero in the string not the input array.

0 1 2

3 4 5

上面是index,那么0在0,可以挪动到{1,3},0在1的位子,可以挪到{0,2,4},以此类推,因为string,所以这些index是可以用来互换的。

class Solution {
    private String target = "123450";
    public int slidingPuzzle(int[][] board) {
        int m = board.length;
        int n = board[0].length;
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                sb.append(board[i][j]);
            }
        }
        
        Queue<String> queue = new LinkedList<>();
        HashSet<String> visited = new HashSet<>();
        queue.offer(sb.toString());
        visited.add(sb.toString());
        
        int step = 0;
        while(!queue.isEmpty()) {
            int size = queue.size();
            for(int i = 0; i < size; i++) {
                String node = queue.poll();
                if(node.equals(target)) {
                    return step;
                }
                for(String neighbor: getNeighbors(node)) {
                    if(!visited.contains(neighbor)) {
                        queue.offer(neighbor);
                        visited.add(neighbor);
                    }
                }
            }
            step++;
        }
        return -1;
    }
    
    private List<String> getNeighbors(String  node) {
        int[][] dirs = new int[][] {{1, 3},{0,2,4},{1,5},{0,4},{1,3,5},{2,4}};
        List<String> list = new ArrayList<>();
        int index = node.indexOf('0');
        for(int i = 0; i < dirs[index].length; i++) {
            StringBuilder sb = new StringBuilder(node);
            swap(sb, index, dirs[index][i], list);
        }
        return list;
    }
    
    private void swap(StringBuilder sb, int i, int j, List<String> list) {
        if(i != j) {
            char temp = sb.charAt(i);
            sb.setCharAt(i, sb.charAt(j));
            sb.setCharAt(j, temp);
            list.add(sb.toString());
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值