【LeetCode每日一题】1345:跳跃游戏 IV

120 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。

1345:跳跃游戏 IV

题意

给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。

每一步,你可以从下标 i 跳到下标:

  • i + 1 满足:i + 1 < arr.length
  • i - 1 满足:i - 1 >= 0
  • j 满足:arr[i] == arr[j] 且 i != j

请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。

注意:任何时候你都不能跳到数组外面。

示例1:

输入:arr = [100,-23,-23,404,100,23,23,23,3,404] 输出:3 解释:那你需要跳跃 3 次,下标依次为 0 --> 4 --> 3 --> 9 。下标 9 为数组的最后一个元素的下标。

示例2:

输入:arr = [7,6,9,6,9,6,9,7] 输出:1 解释:你可以直接从下标 0 处跳到下标 7 处,也就是数组的最后一个元素处。

示例3:

输入:arr = [11,22,7,7,7,7,7,7,7,22,13] 输出:3

题解:BFS

首先将相同值存入map中(value为数组),然后bfs遍历求最短路径

C++代码:

class Solution {
public:
    int inf=0x3f3f3f3f;
    int minJumps(vector<int>& a) {
        int n=a.size();
        map<int,vector<int> > mp;
        //初始化map
        for(int i=0;i<n;i++) mp[a[i]].push_back(i);
        vector<int> dis(n,inf);
        queue<int> q;
        q.push(0);dis[0]=0;
​
        while(!q.empty()){
            int u=q.front(),now=dis[u];q.pop();
            if(u==n-1) return now;
            if(u+1<n&&dis[u+1]==inf){
                q.push(u+1);dis[u+1]=now+1;
            }
            if(u-1>=0&&dis[u-1]==inf){
                q.push(u-1);dis[u-1]=now+1;
            }
            for(int i=0;i<mp[a[u]].size();i++){
                if(dis[mp[a[u]][i]]==inf){
                    q.push(mp[a[u]][i]);
                    dis[mp[a[u]][i]]=now+1;
                }
            }
            //注意需要在map中清空当前值
            mp[a[u]].clear();
        }
        return -1;
    }
};

Java代码:

class Solution {
    int inf = 0x3f3f3f3f;
​
    public int minJumps(int[] arr) {
        int n = arr.length;
        Map<Integer, List<Integer>> mp = new HashMap<>();
        // 初始化map
        for (int i = 0; i < n; i++) {
            List<Integer> list = mp.getOrDefault(arr[i], new ArrayList<>());
            list.add(i);
            mp.put(arr[i], list);
        }
        int dis[] = new int[n];
        Arrays.fill(dis, inf);
        ArrayDeque<Integer> q = new ArrayDeque();
        q.add(0);
        dis[0] = 0;
        while (!q.isEmpty()) {
            int u = q.poll();
            int now = dis[u];
            if (u == n - 1)
                return now;
            if (u + 1 < n && dis[u + 1] == inf) {
                q.add(u + 1);
                dis[u + 1] = now + 1;
            }
            if (u - 1 >= 0 && dis[u - 1] == inf) {
                q.add(u - 1);
                dis[u - 1] = now + 1;
            }
            List<Integer> list = mp.getOrDefault(arr[u], new ArrayList<>());
            for (int i : list) {
                if (dis[i] == inf) {
                    q.add(i);
                    dis[i] = now + 1;
                }
            }
            // 在map中清空当前值
            mp.getOrDefault(arr[u], new ArrayList<>()).clear();
        }
        return -1;
    }
}