题目

Given an array of integers arr, you are initially positioned at the first index of the array.

In one step you can jump from index i to index:

  • i + 1 where: i + 1 < arr.length.
  • i - 1 where: i - 1 >= 0.
  • j where: arr[i] == arr[j] and i != j.

Return the minimum number of steps to reach the last index of the array.

Notice that you can not jump outside of the array at any time.

Example 1:

  1. Input: arr = [100,-23,-23,404,100,23,23,23,3,404]
  2. Output: 3
  3. Explanation: You need three jumps from index 0 --> 4 --> 3 --> 9. Note that index 9 is the last index of the array.

Example 2:

  1. Input: arr = [7]
  2. Output: 0
  3. Explanation: Start index is the last index. You don't need to jump.

Example 3:

  1. Input: arr = [7,6,9,6,9,6,9,7]
  2. Output: 1
  3. Explanation: You can jump directly from index 0 to index 7 which is last index of the array.

Example 4:

  1. Input: arr = [6,1,9]
  2. Output: 2

Example 5:

  1. Input: arr = [11,22,7,7,7,7,7,7,7,22,13]
  2. Output: 3

Constraints:

  • 1 <= arr.length <= 5 * 10^4
  • -10^8 <= arr[i] <= 10^8

题意

给定一个数组,对应其中一个下标i,下一步可以到达的下标为i-1、i+1、所有满足arr[i]==arr[j]的j。要求能从0到达最后一个下标的最小步数。

思路

按照提示,将数组重构成一张表,结点的值是数组中的下标,且与前后两个下标对应的结点、所有与该结点在数组中对应的值相等的结点相连。用BFS找最短距离。


代码实现

Java

  1. class Solution {
  2. public int minJumps(int[] arr) {
  3. if (arr.length == 1) {
  4. return 0;
  5. }
  6. Map<Integer, List<Integer>> inverse = new HashMap<>();
  7. for (int i = 0; i < arr.length; i++) {
  8. inverse.putIfAbsent(arr[i], new ArrayList<>());
  9. inverse.get(arr[i]).add(i);
  10. }
  11. int steps = 0;
  12. Queue<Integer> q = new LinkedList<>();
  13. boolean[] visited = new boolean[arr.length];
  14. visited[0] = true;
  15. q.offer(0);
  16. while (!q.isEmpty()) {
  17. int size = q.size();
  18. for (int i = 0; i < size; i++) {
  19. int cur = q.poll();
  20. for (int j = inverse.get(arr[cur]).size() - 1; j >= 0; j--) {
  21. int next = inverse.get(arr[cur]).get(j);
  22. if (next != cur && !visited[next]) {
  23. if (next == arr.length - 1) return steps + 1;
  24. q.offer(next);
  25. visited[next] = true;
  26. }
  27. }
  28. if (cur > 0 && !visited[cur - 1]) {
  29. q.offer(cur - 1);
  30. visited[cur - 1] = true;
  31. }
  32. if (cur < arr.length - 1 && !visited[cur + 1]) {
  33. if (cur + 1 == arr.length - 1) return steps + 1;
  34. q.offer(cur + 1);
  35. visited[cur + 1] = true;
  36. }
  37. }
  38. steps++;
  39. }
  40. return -1;
  41. }
  42. }