题目
给你一个整数数组 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;
}
}