1345. 跳跃游戏 IV

exiaohu 于 2022-01-21 发布

题目链接:1345. 跳跃游戏 IV

在存在密集子图的情况下对 dijkstra 算法的优化。

普通的 dijkstra 算法:

import heapq
from collections import defaultdict


def dijkstra(edges, f, t):
    g = defaultdict(list)
    for l, r, c in edges:
        g[l].append((c, r))

    # dist records the min value of each node in heap.
    q, seen, dist = [(0, f)], set(), {f: 0}
    while len(q) > 0:
        cost, v1 = heapq.heappop(q)
        if v1 in seen:
            continue

        seen.add(v1)
        if v1 == t:
            return cost

        for c, v2 in g.get(v1, ()):
            if v2 in seen:
                continue
            # Not every edge will be calculated. Edges which can improve the value of node in heap will be useful.
            if v2 not in dist or cost + c < dist[v2]:
                dist[v2] = cost + c
                heapq.heappush(q, (cost + c, v2))
    return float("inf")

在访问到一个结点时,也将该结点与其值相同的结点都加入队列,并将该密集子图删除,防止下次再次访问该结点。

import heapq
from collections import defaultdict
from typing import List


class Solution:
    def minJumps(self, arr: List[int]) -> int:
        keymap = defaultdict(list)
        for i, a in enumerate(arr):
            keymap[a].append(i)

        visited, q = {0}, []
        heapq.heappush(q, (0, 0))
        while len(q) > 0:
            step, idx = heapq.heappop(q)
            if idx == len(arr) - 1:
                return step

            v = arr[idx]
            step += 1

            for i in keymap[v]:
                if i not in visited:
                    visited.add(i)
                    q.append((step, i))

            del keymap[v]  # important optimization, don't need to visit the same nodes next

            if idx + 1 < len(arr) and (idx + 1) not in visited:
                visited.add(idx + 1)
                q.append((step, idx + 1))
            if idx - 1 >= 0 and (idx - 1) not in visited:
                visited.add(idx - 1)
                q.append((step, idx - 1))