持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。
1345:跳跃游戏 IV
题意
给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。
每一步,你可以从下标 i 跳到下标:
- i + 1 满足:i + 1 < arr.length
- i - 1 满足:i - 1 >= 0
- j 满足:arr[i] == arr[j] 且 i != j
请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。
注意:任何时候你都不能跳到数组外面。
示例1:
输入:arr = [100,-23,-23,404,100,23,23,23,3,404] 输出:3 解释:那你需要跳跃 3 次,下标依次为 0 --> 4 --> 3 --> 9 。下标 9 为数组的最后一个元素的下标。
示例2:
输入:arr = [7,6,9,6,9,6,9,7] 输出:1 解释:你可以直接从下标 0 处跳到下标 7 处,也就是数组的最后一个元素处。
示例3:
输入:arr = [11,22,7,7,7,7,7,7,7,22,13] 输出:3
题解:BFS
首先将相同值存入map中(value为数组),然后bfs遍历求最短路径
C++代码:
class Solution {
public:
int inf=0x3f3f3f3f;
int minJumps(vector<int>& a) {
int n=a.size();
map<int,vector<int> > mp;
//初始化map
for(int i=0;i<n;i++) mp[a[i]].push_back(i);
vector<int> dis(n,inf);
queue<int> q;
q.push(0);dis[0]=0;
while(!q.empty()){
int u=q.front(),now=dis[u];q.pop();
if(u==n-1) return now;
if(u+1<n&&dis[u+1]==inf){
q.push(u+1);dis[u+1]=now+1;
}
if(u-1>=0&&dis[u-1]==inf){
q.push(u-1);dis[u-1]=now+1;
}
for(int i=0;i<mp[a[u]].size();i++){
if(dis[mp[a[u]][i]]==inf){
q.push(mp[a[u]][i]);
dis[mp[a[u]][i]]=now+1;
}
}
//注意需要在map中清空当前值
mp[a[u]].clear();
}
return -1;
}
};
Java代码:
class Solution {
int inf = 0x3f3f3f3f;
public int minJumps(int[] arr) {
int n = arr.length;
Map<Integer, List<Integer>> mp = new HashMap<>();
// 初始化map
for (int i = 0; i < n; i++) {
List<Integer> list = mp.getOrDefault(arr[i], new ArrayList<>());
list.add(i);
mp.put(arr[i], list);
}
int dis[] = new int[n];
Arrays.fill(dis, inf);
ArrayDeque<Integer> q = new ArrayDeque();
q.add(0);
dis[0] = 0;
while (!q.isEmpty()) {
int u = q.poll();
int now = dis[u];
if (u == n - 1)
return now;
if (u + 1 < n && dis[u + 1] == inf) {
q.add(u + 1);
dis[u + 1] = now + 1;
}
if (u - 1 >= 0 && dis[u - 1] == inf) {
q.add(u - 1);
dis[u - 1] = now + 1;
}
List<Integer> list = mp.getOrDefault(arr[u], new ArrayList<>());
for (int i : list) {
if (dis[i] == inf) {
q.add(i);
dis[i] = now + 1;
}
}
// 在map中清空当前值
mp.getOrDefault(arr[u], new ArrayList<>()).clear();
}
return -1;
}
}