image.png
    image.png

    广度优先搜索

    队列里记录的永远是某个点可以最少到达的步数,一旦遍历过就不可以再次造访,这样就能保证到达终点的步数是最小的

    1. /*
    2. @可爱抱抱呀
    3. 执行用时:46 ms, 在所有 Java 提交中击败了63.21%的用户
    4. 内存消耗:51.6 MB, 在所有 Java 提交中击败了69.43%的用户
    5. 2022年1月20日 12:58
    6. */
    7. class Solution {
    8. public int minJumps(int[] arr) {
    9. if(arr.length==1){return 0;}
    10. boolean cameBefore[]=new boolean[arr.length];
    11. Map<Integer,List<Integer>> map=new HashMap<>();
    12. for(int i=0;i<arr.length;i++){
    13. if(!map.containsKey(arr[i])){map.put(arr[i],new ArrayList<>());}
    14. map.get(arr[i]).add(i);
    15. }
    16. Queue<int[]> q=new LinkedList<>();//{坐标,步数}
    17. cameBefore[0]=true;
    18. q.add(new int[]{0,0});
    19. while(q.size()>0){
    20. int a[]=q.poll();//每个点拿出后,检查所有同值的点,以及前后的点
    21. if(a[0]+1==arr.length-1){return a[1]+1;}
    22. if(!cameBefore[a[0]+1]){
    23. cameBefore[a[0]+1]=true;
    24. q.add(new int[]{a[0]+1,a[1]+1});
    25. }
    26. if(a[0]>1&&!cameBefore[a[0]-1]){
    27. cameBefore[a[0]-1]=true;
    28. q.add(new int[]{a[0]-1,a[1]+1});
    29. }
    30. if(map.containsKey(arr[a[0]])){
    31. List<Integer> list=map.get(arr[a[0]]);
    32. for(int i=0;i<list.size();i++){
    33. if(list.get(i)-a[0]!=0&&!cameBefore[list.get(i)]){
    34. if(list.get(i)-arr.length+1==0){return a[1]+1;}
    35. cameBefore[list.get(i)]=true;
    36. q.add(new int[]{list.get(i),a[1]+1});
    37. }
    38. }
    39. map.remove(arr[a[0]]);//过河拆桥
    40. }
    41. }
    42. return -1;
    43. }
    44. }
    1. class Solution {
    2. public int minJumps(int[] arr) {
    3. Map<Integer, List<Integer>> map = new HashMap<>();
    4. for (int i = 0; i < arr.length; i++) {
    5. if (i > 0 && i < arr.length - 1 && arr[i - 1] == arr[i] && arr[i + 1] == arr[i]) continue;
    6. if (i > 1 && i < arr.length - 2 && arr[i - 2] == arr[i] && arr[i + 2] == arr[i] && arr[i - 1] == arr[i + 1]) continue;
    7. map.putIfAbsent(arr[i], new ArrayList<>());
    8. map.get(arr[i]).add(i);
    9. }
    10. boolean[] visited = new boolean[arr.length];
    11. int step = 0;
    12. Queue<Integer> queue = new LinkedList<>();
    13. queue.add(0);
    14. visited[0] = true;
    15. while (!queue.isEmpty()) {
    16. int size = queue.size();
    17. for (int i = 0; i < size; i++) {
    18. int idx = queue.poll();
    19. if (idx == arr.length - 1) return step;
    20. // 向后走
    21. if (idx + 1 < arr.length && !visited[idx + 1]) {
    22. if (idx + 1 == arr.length - 1) return step + 1;
    23. queue.offer(idx + 1);
    24. visited[idx + 1] = true;
    25. }
    26. // 向前走
    27. if (idx - 1 >= 0 && !visited[idx - 1]) {
    28. queue.offer(idx - 1);
    29. visited[idx - 1] = true;
    30. }
    31. // 向相同的元素走
    32. if (map.containsKey(arr[idx])) {
    33. for (int j : map.get(arr[idx])) {
    34. if (!visited[j]) {
    35. if (j == arr.length - 1) return step + 1;
    36. queue.offer(j);
    37. visited[j] = true;
    38. }
    39. }
    40. map.remove(arr[idx]);//过河拆桥
    41. }
    42. }
    43. step++;
    44. }
    45. return step;
    46. }
    47. }