909. 蛇梯棋
https://leetcode.cn/problems/snakes-and-ladders/description/?envType=study-plan-v2&envId=top-interview-150
思路:题目要求我们使用最小的步数走到终点(注意不能走回头路,传送不算),那我们的想法就很明确了,我们遍历所有可以走到终点的方法然后找出最小的那个就行,怎么找到所有的方法呢,bfs就很适合我们,每一层就代表我们这一步的所有落点情况。
我们可以先分析一下这个矩阵的规律,如果nn&1==0
并且 x&1 == 1(奇数层),board[x][y] = (nn-x-1)* nn + (y + 1)
*x&1 == 0(偶数层), board[x][y] = (nn-x-1)* nn + (nn - y)
如果nn&1==1上述情况就反一下。
所以我们知道当前的下标就可以推出在board中的二维下标
nn&1 == 0:
如果((index-1)/nn + 1) & 1 = 0(奇数层),x = nn - ((index-1)/nn + 1) , y = (index - 1)% nn
如果((index-1)/nn + 1) & 1 = 1(偶数层),x = nn - ((index-1)/nn + 1) , y = nn - ((index - 1) % nn) - 1
nn&1 == 1就把奇偶的规律反一下
class Solution {public int snakesAndLadders(int[][] board) {int n = board.length * board[0].length; // 终点int currIndex = 1; // 当前下标int currStepNum = 0; // 当前步数Queue<Integer> currStep = new LinkedList<>(); // 当前位置currStep.offer(currIndex);Queue<Integer> nextStep = new LinkedList<>(); // 下一步数所有可落点下标boolean[] signed = new boolean[n + 1]; // 标记点有没有走过signed[1] = true;int ans = Integer.MAX_VALUE;while (!currStep.isEmpty()) {currStepNum++;if(currStepNum > ans) break;while (!currStep.isEmpty()) {int curr = currStep.poll();for (int i = 1; i <= 6; i++) {int nextIndex = getNextIndex(board, curr, i);if(nextIndex == n) {// 走到终点了ans = Math.min(ans, currStepNum);continue;}if(nextIndex == -1 || signed[nextIndex]) {// 超出边界了或走过了continue;}nextStep.add(nextIndex); // 加入下一步signed[nextIndex] = true;}}// 交换currStep = nextStep;nextStep = new LinkedList<>();}return ans == Integer.MAX_VALUE ? -1 : ans;}public int getNextIndex(int[][] board, int currIndex, int stepLength) {int nn = board.length;int nextIndex = currIndex + stepLength;if(nextIndex > nn * nn) {return -1;}int x = nn - ((nextIndex - 1) / nn + 1);int y = 0;if((nn & 1) == 0) {if((x & 1) == 1) {y = (nextIndex - 1) % nn;} else {y = nn - ((nextIndex - 1) % nn) - 1;}} else {if ((x & 1) == 1) {y = nn - ((nextIndex - 1) % nn) - 1;} else {y = (nextIndex - 1) % nn;}}// 如果有梯子或蛇,则跳到指定位置return board[x][y] == -1 || nextIndex == nn*nn ? nextIndex : board[x][y];}public static void main(String[] args) {Solution solution = new Solution();System.out.println(solution.snakesAndLadders(new int[][]{{1, 1, -1}, {1, 1, 1}, {-1, 1, 1}}));}
}