LeetCode 每日一题笔记 日期:2026.05.18 题目:1345. 跳跃游戏 IV

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.05.18
  • 题目:1345. 跳跃游戏 IV
  • 难度:困难
  • 标签:数组、广度优先搜索、哈希表

1. 题目理解

问题描述

给定一个整数数组 arr,你从下标 0 开始。每一步可以从下标 i 跳到:

  1. i + 1(需满足 i + 1 < arr.length
  2. i - 1(需满足 i - 1 >= 0
  3. 任意 j(需满足 arr[j] == arr[i]j != i

求到达数组最后一个下标的最少操作次数

示例

输入:arr = [100,-23,-23,404,100,23,23,23,3,404]

输出:3

解释:最优路径:0 → 4 → 3 → 9,共3次跳跃。
输入:arr = [7]

输出:0

解释:初始位置就是终点,无需跳跃。

2. 解题思路

核心观察

  • 这是典型的无权图最短路径问题,BFS是天然的最优解法;
  • 同值跳跃会产生大量边,若不优化会导致超时;
  • 关键优化:处理完一个值的所有下标后,立即从哈希表移除该值,避免重复处理。

算法步骤

  1. 预处理哈希表:建立「值 → 对应下标列表」的映射;
  2. BFS初始化:队列加入起点 0,标记已访问;
  3. 逐层遍历队列,每层对应一步操作;
  4. 对当前节点,依次处理:
    • 右邻居 i+1
    • 左邻居 i-1
    • 所有同值下标
  5. 处理完同值下标后,从哈希表移除该值;
  6. 到达终点时立即返回当前步数。

3. 代码实现

java 复制代码
package lc1345;

import java.util.*;

class Solution {

    int bfs(HashMap<Integer, List<Integer>> map, int[] arr) {
        int res = 0;
        int last = arr.length - 1;
        boolean[] visited = new boolean[arr.length];
        Queue<Integer> queue = new LinkedList();
        queue.offer(0);
        while (!queue.isEmpty()) {
            int m = queue.size();
            for (int i = 0; i < m; i++) {
                int n = queue.poll();
                visited[n] = true;
                if (n == last) {
                    return res;
                }
                if (n < last && !visited[n + 1]) {
                    visited[n + 1] = true;
                    queue.offer(n + 1);
                }
                if (n > 0 && !visited[n - 1]) {
                    visited[n - 1] = true;
                    queue.offer(n - 1);
                }
                if (map.containsKey(arr[n])) {
                    List<Integer> list = map.get(arr[n]);
                    for (int num : list) {
                        if (num != n && !visited[num]) {
                            visited[num] = true;
                            queue.offer(num);
                        }
                    }
                    map.remove(arr[n]);
                }
            }
            res += 1;
        }
        return -1;
    }

    public int minJumps(int[] arr) {
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        for (int i = arr.length - 1; i >= 0; i--) {
            map.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i);
        }
        return bfs(map, arr);
    }
}

4. 代码优化说明

减少if分支判断,合并重复逻辑,使用更高效的队列实现:

java 复制代码
package lc1345;

import java.util.*;

class Solution {
    public int minJumps(int[] arr) {
        int n = arr.length;
        if (n == 1) return 0;
        
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            map.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i);
        }
        
        boolean[] visited = new boolean[n];
        Queue<Integer> queue = new ArrayDeque<>();
        queue.offer(0);
        visited[0] = true;
        int step = 0;
        
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int curr = queue.poll();
                if (curr == n - 1) return step;
                
                // 处理左右邻居
                if (curr + 1 < n && !visited[curr + 1]) {
                    visited[curr + 1] = true;
                    queue.offer(curr + 1);
                }
                if (curr - 1 >= 0 && !visited[curr - 1]) {
                    visited[curr - 1] = true;
                    queue.offer(curr - 1);
                }
                
                // 处理同值下标
                if (map.containsKey(arr[curr])) {
                    for (int next : map.get(arr[curr])) {
                        if (!visited[next]) {
                            visited[next] = true;
                            queue.offer(next);
                        }
                    }
                    map.remove(arr[curr]);
                }
            }
            step++;
        }
        return -1;
    }
}

5. 复杂度分析

  • 时间复杂度 :O(n)O(n)O(n)

    • 每个下标最多入队一次,每个值最多处理一次;
    • 哈希表移除操作避免了重复处理同值下标,是不超时的关键。
  • 空间复杂度 :O(n)O(n)O(n)

    • 哈希表、队列、访问数组的空间开销均为线性级。

6. 总结

  • 核心思路:BFS 求最短路径 + 哈希表批量处理同值跳跃
  • 关键优化:处理完一个值的所有下标后立即从哈希表移除,避免重复入队;
  • 本题是 BFS 在数组跳跃问题中的经典应用,重点考察对时间复杂度的优化能力。
相关推荐
问心无愧05132 小时前
ctf show web入门98
android·前端·笔记
Misnearch2 小时前
1345. 跳跃游戏 IV
java·leetcode·bfs
想七想八不如114082 小时前
markdown笔记(没找到合适笔记软件,暂存)
笔记·目标检测
脑子不好真君2 小时前
system-design-primer学习笔记——Updating
笔记·学习
德迅云安全-小潘2 小时前
游戏行业面临的网络安全挑战
安全·web安全·游戏
星恒随风2 小时前
从0开始的操作系统学习之路(2)
c语言·笔记·学习
daanpdf2 小时前
高中数学必修一必修二课本习题答案人教版(A版+B版)
笔记
九成宫2 小时前
WSL2 网络优化配置:提升Git克隆与包下载速度
windows·笔记·代理模式·pip·wsl
羊群智妍2 小时前
2026 GEO实战:AI搜索优化监测工具选型与用法
笔记