一、Problem
Given an array of integers arr, you are initially positioned at the first index of the array.
In one step you can jump from index i to index:
- i + 1 where: i + 1 < arr.length.
- i - 1 where: i - 1 >= 0.
- j where: arr[i] == arr[j] and i != j.
Return the minimum number of steps to reach the last index of the array.
Notice that you can not jump outside of the array at any time.
Input: arr = [100,-23,-23,404,100,23,23,23,3,404]
Output: 3
Explanation: You need three jumps from index 0 --> 4 --> 3 --> 9. Note that index 9 is the last index of the array.
二、Solution
方法一:bfs
Q&A:
- Q1:爲什麼不是 dp?
A1:因爲同一個位置可能存在多次跳躍,也就是說,已經後面跳過的位置會影響前面跳過的位置,不符合 dp 的無後效性。
class Solution {
int n, A[];
Map<Integer, List<Integer>> mp;
int bfs(int S) {
Queue<Integer> q = new ArrayDeque<>();
q.add(S);
boolean[] vis = new boolean[n];
int s = 0;
vis[S] = true;
while (!q.isEmpty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
int cur = q.poll();
if (cur == n-1)
return s;
if (cur + 1 < n && !vis[cur+1]) {
q.add(cur+1);
vis[cur+1] = true;
}if (cur - 1 >= 0 && !vis[cur-1]) {
q.add(cur-1);
vis[cur-1] = true;
}for (int idx : mp.get(A[cur])) {
if (!vis[idx]) {
q.add(idx);
vis[idx] = true;
}
}
}
s++;
}
return 0;
}
public int minJumps(int[] A) {
n = A.length;
this.A = A;
mp = new HashMap<>();
for (int i = 0; i < n; i++) {
mp.computeIfAbsent(A[i], k -> new ArrayList<>()).add(i);
}
return bfs(0);
}
}
Q2:爲什麼下面的程序會超時,加了記錄數組了呀?
A2:觀察到有一個很長的都是相同元素的輸入,又由於 bfs 第一次到達一個位置一定是花費最少,所以再次跳到相同的元素的位置是沒有意義的,而每次都對取 for 遍歷這些相同元素會造成時間浪費。
class Solution {
int n, A[];
Map<Integer, List<Integer>> mp;
int bfs(int S) {
Queue<Integer> q = new ArrayDeque<>();
q.add(S);
boolean[] vis = new boolean[n];
int s = 0;
vis[S] = true;
while (!q.isEmpty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
int cur = q.poll();
if (cur == n-1)
return s;
if (mp.get(A[cur]) != null)
for (int idx : mp.get(A[cur])) {
if (!vis[idx]) {
q.add(idx);
vis[idx] = true;
}
}
mp.remove(A[cur]);
if (cur + 1 < n && !vis[cur+1]) {
q.add(cur+1);
vis[cur+1] = true;
}if (cur - 1 >= 0 && !vis[cur-1]) {
q.add(cur-1);
vis[cur-1] = true;
}
}
s++;
}
return 0;
}
public int minJumps(int[] A) {
n = A.length;
this.A = A;
mp = new HashMap<>();
for (int i = 0; i < n; i++) {
mp.computeIfAbsent(A[i], k -> new ArrayList<>()).add(i);
}
return bfs(0);
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:雙向 bfs
代辦…