Leetcode 1345 跳跃游戏 IV

25 篇文章 0 订阅
9 篇文章 0 订阅
题目

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

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

i + 1 满足:i + 1 < arr.length
i - 1 满足:i - 1 >= 0
j 满足:arr[i] == arr[j] 且 i != j
请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。

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

解题思路

  BFS。每次走 index - 1 index + 1 arr[i] == arr[j] 且 i != j ,走过的地方要标记,因为BFS走过的每一个节点都是最小步数;对于一样的 value ,走过一次就没必要再走了,所以在建的图中得销毁。

  睡觉前看这题想着建图+BFS应该能过,但后来想到如果全是一样的 value,建图好像会TLE,早上起来就没写这题。下午的时候又想到这题了,好像对于同一个 value ,只用走一次标记一下就行了,那么就是普通的BFS了,写了一下交了就过了。

代码
class Node {
    int index, step;

    public Node(int index, int step) {
        this.index = index;
        this.step = step;
    }
}
class Solution {
    public int minJumps(int[] arr) {
        int length = arr.length;
        Map<Integer, List<Integer>> map = new HashMap<>();
        Queue<Node> queue = new ArrayDeque<>();
        Boolean[] flag = new Boolean[length];

        for (int i = 0; i < length; i++) {
            List<Integer> tmp = map.getOrDefault(arr[i], new ArrayList<>());
            tmp.add(i);
            map.put(arr[i], tmp);
            flag[i] = false;
        }
        queue.offer(new Node(0, 0));
        flag[0] = true;
        while (!queue.isEmpty()) {
            Node now = queue.poll();
            if (now.index == length - 1) return now.step;
            if (now.index > 0 && !flag[now.index - 1]) {
                queue.offer(new Node(now.index - 1, now.step + 1));
                flag[now.index - 1] = true;
            }
            if (now.index < length - 1 && !flag[now.index + 1]) {
                queue.offer(new Node(now.index + 1, now.step + 1));
                flag[now.index + 1] = true;
            }
            if (map.containsKey(arr[now.index])) {
                List<Integer> nextIndexes = map.getOrDefault(arr[now.index], new ArrayList<>());
                for (Integer nextIndex : nextIndexes) {
                    if (!flag[nextIndex]) {
                        queue.offer(new Node(nextIndex, now.step + 1));
                        flag[nextIndex] = true;
                    }
                }
                map.remove(arr[now.index]);
            }
        }
        return -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值