返回介绍

solution / 1600-1699 / 1654.Minimum Jumps to Reach Home / README_EN

发布于 2024-06-17 01:03:16 字数 8980 浏览 0 评论 0 收藏 0

1654. Minimum Jumps to Reach Home

中文文档

Description

A certain bug's home is on the x-axis at position x. Help them get there from position 0.

The bug jumps according to the following rules:

  • It can jump exactly a positions forward (to the right).
  • It can jump exactly b positions backward (to the left).
  • It cannot jump backward twice in a row.
  • It cannot jump to any forbidden positions.

The bug may jump forward beyond its home, but it cannot jump to positions numbered with negative integers.

Given an array of integers forbidden, where forbidden[i] means that the bug cannot jump to the position forbidden[i], and integers a, b, and x, return _the minimum number of jumps needed for the bug to reach its home_. If there is no possible sequence of jumps that lands the bug on position x, return -1.

 

Example 1:

Input: forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9
Output: 3
Explanation: 3 jumps forward (0 -> 3 -> 6 -> 9) will get the bug home.

Example 2:

Input: forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11
Output: -1

Example 3:

Input: forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7
Output: 2
Explanation: One jump forward (0 -> 16) then one jump backward (16 -> 7) will get the bug home.

 

Constraints:

  • 1 <= forbidden.length <= 1000
  • 1 <= a, b, forbidden[i] <= 2000
  • 0 <= x <= 2000
  • All the elements in forbidden are distinct.
  • Position x is not forbidden.

Solutions

Solution 1: BFS

We can use the position and jumping direction of the flea as the state, and use BFS to search for the shortest path. The key point of this problem is to determine the right boundary, that is, how far the flea can jump.

If $a \geq b$, that is, the distance to jump forward is greater than the distance to jump backward, then if the flea is in a position greater than $x+b$, it can no longer jump forward, because the flea cannot jump backward consecutively. If it continues to jump forward, it will never be able to jump to the position $x$. Therefore, if $a \geq b$, the right boundary can be $x+b$.

If $a < b$, that is, the distance to jump forward is less than the distance to jump backward, then if the position of the flea minus $b$ exceeds $2000$, choose to jump backward, otherwise jump forward. Therefore, if $a < b$, the right boundary does not exceed $6000$.

In summary, we can set the right boundary to $6000$.

Next, we use BFS to search for the shortest path. We use a queue, initially adding the position and jumping direction of the flea as the state to the queue. Each time we take a state from the queue, if the position of this state is equal to $x$, then we have found a path from the initial state to the target state, and we can return the current number of steps. Otherwise, we add the next state of the current state to the queue. There are two cases for the next state:

  • Jump forward, the jumping direction is $1$;
  • When the current jumping direction is $1$, jump backward, the jumping direction is $0$.

Note that we need to judge whether the next state is legal, that is, the position of the next state does not exceed the right boundary, is not in the forbidden position, and has not been visited.

If the queue is empty, it means that the target position cannot be reached, return $-1$.

The time complexity is $O(M)$, and the space complexity is $O(M)$. Here, $M$ is the right boundary, and in this problem, $M \leq 6000$.

class Solution:
  def minimumJumps(self, forbidden: List[int], a: int, b: int, x: int) -> int:
    s = set(forbidden)
    q = deque([(0, 1)])
    vis = {(0, 1)}
    ans = 0
    while q:
      for _ in range(len(q)):
        i, k = q.popleft()
        if i == x:
          return ans
        nxt = [(i + a, 1)]
        if k & 1:
          nxt.append((i - b, 0))
        for j, k in nxt:
          if 0 <= j < 6000 and j not in s and (j, k) not in vis:
            q.append((j, k))
            vis.add((j, k))
      ans += 1
    return -1
class Solution {
  public int minimumJumps(int[] forbidden, int a, int b, int x) {
    Set<Integer> s = new HashSet<>();
    for (int v : forbidden) {
      s.add(v);
    }
    Deque<int[]> q = new ArrayDeque<>();
    q.offer(new int[] {0, 1});
    final int n = 6000;
    boolean[][] vis = new boolean[n][2];
    vis[0][1] = true;
    for (int ans = 0; !q.isEmpty(); ++ans) {
      for (int t = q.size(); t > 0; --t) {
        var p = q.poll();
        int i = p[0], k = p[1];
        if (i == x) {
          return ans;
        }
        List<int[]> nxt = new ArrayList<>();
        nxt.add(new int[] {i + a, 1});
        if ((k & 1) == 1) {
          nxt.add(new int[] {i - b, 0});
        }
        for (var e : nxt) {
          int j = e[0];
          k = e[1];
          if (j >= 0 && j < n && !s.contains(j) && !vis[j][k]) {
            q.offer(new int[] {j, k});
            vis[j][k] = true;
          }
        }
      }
    }
    return -1;
  }
}
class Solution {
public:
  int minimumJumps(vector<int>& forbidden, int a, int b, int x) {
    unordered_set<int> s(forbidden.begin(), forbidden.end());
    queue<pair<int, int>> q;
    q.emplace(0, 1);
    const int n = 6000;
    bool vis[n][2];
    memset(vis, false, sizeof(vis));
    vis[0][1] = true;
    for (int ans = 0; q.size(); ++ans) {
      for (int t = q.size(); t; --t) {
        auto [i, k] = q.front();
        q.pop();
        if (i == x) {
          return ans;
        }
        vector<pair<int, int>> nxts = {{i + a, 1}};
        if (k & 1) {
          nxts.emplace_back(i - b, 0);
        }
        for (auto [j, l] : nxts) {
          if (j >= 0 && j < n && !s.count(j) && !vis[j][l]) {
            vis[j][l] = true;
            q.emplace(j, l);
          }
        }
      }
    }
    return -1;
  }
};
func minimumJumps(forbidden []int, a int, b int, x int) (ans int) {
  s := map[int]bool{}
  for _, v := range forbidden {
    s[v] = true
  }
  q := [][2]int{[2]int{0, 1}}
  const n = 6000
  vis := make([][2]bool, n)
  vis[0][1] = true
  for ; len(q) > 0; ans++ {
    for t := len(q); t > 0; t-- {
      p := q[0]
      q = q[1:]
      i, k := p[0], p[1]
      if i == x {
        return
      }
      nxt := [][2]int{[2]int{i + a, 1}}
      if k&1 == 1 {
        nxt = append(nxt, [2]int{i - b, 0})
      }
      for _, e := range nxt {
        j, l := e[0], e[1]
        if j >= 0 && j < n && !s[j] && !vis[j][l] {
          q = append(q, [2]int{j, l})
          vis[j][l] = true
        }
      }
    }
  }
  return -1
}
function minimumJumps(forbidden: number[], a: number, b: number, x: number): number {
  const s: Set<number> = new Set(forbidden);
  const q: [number, number][] = [[0, 1]];
  const n = 6000;
  const vis: boolean[][] = Array.from({ length: n }, () => [false, false]);
  vis[0][1] = true;
  for (let ans = 0; q.length; ++ans) {
    for (let t = q.length; t; --t) {
      const [i, k] = q.shift()!;
      if (i === x) {
        return ans;
      }
      const nxt: [number, number][] = [[i + a, 1]];
      if (k & 1) {
        nxt.push([i - b, 0]);
      }
      for (const [j, k] of nxt) {
        if (j >= 0 && j < n && !s.has(j) && !vis[j][k]) {
          vis[j][k] = true;
          q.push([j, k]);
        }
      }
    }
  }
  return -1;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文