1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| class Solution { private static class Node { int pos; boolean canMoveBack;
Node(int _pos, boolean _canMoveBack) { pos = _pos; canMoveBack = _canMoveBack; } }
public int minimumJumps(int[] forbidden, int a, int b, int x) { if (x == 0) { return 0; } int furthest = 2000 + 2 * b + 1; boolean[] visited = new boolean[furthest]; for (int num : forbidden) { visited[num] = true; } int step = 0; Queue<Node> q = new LinkedList<>(); q.add(new Node(0, false)); visited[0] = true; while (!q.isEmpty()) { int size = q.size(); for (int i = 0; i < size; i++) { Node currNode = q.poll(); if (currNode.pos == x) { return step; } if (currNode.canMoveBack && currNode.pos - b > 0 && !visited[currNode.pos - b]) { q.offer(new Node(currNode.pos - b, false)); visited[currNode.pos - b] = true; } if (currNode.pos + a < furthest && !visited[currNode.pos + a]) { q.offer(new Node(currNode.pos + a, true)); visited[currNode.pos + a] = true; } } step += 1; } return -1; } }
|
BFS就是. 关键在于什么时候停. 我看评论区, upper bound是max(num in forbidden, x) + a + b. 但我也不知道为啥.
然后就BFS.
最大的问题就是for循环中要先添加backward, 再添加forward, 要不然不会通过. 我想了很久也不知道为什么.
时间复杂度和空间复杂度我也不知道是什么.
以下是反面教材, 失败的尝试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public int minimumJumps(int[] forbidden, int a, int b, int x) { Map<Integer, Integer> visited = new HashMap<>(); Set<Integer> forbid = new HashSet<>(); for (int pos : forbidden) { forbid.add(pos); } int currPos = 0, backPos = 0, step = 0; while (backPos <= x) { if (forbid.contains(currPos)) { break; } else { if (!visited.containsKey(currPos)) { visited.put(currPos, step); } if (!forbid.contains(backPos) && !visited.containsKey(backPos)) { visited.put(backPos, step + 1); } } currPos += a; backPos = currPos - b; step += 1; } return visited.containsKey(x) ? visited.get(x) : -1; } }
|
失败的尝试. 以为就是往前走一步, 退一步, 然后在退之前的位置再继续走一步退一步. 但我没考虑到退完一步再往前走还有新的可能. 因此这个答案是错误的.