⭐️寒假新坑——代码之狐的每日做题笔记
1345. 跳跃游戏 IV-Hard
题目描述:
给你一个整数数组 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 为数组的最后一个元素的下标。
解题思路:
BFS(广度优先搜索):处理每步到达的节点,添加其下一步能够到达的未到达过的节点(由上述规则)
Hash表:预处理相同节点,记录相同节点的下标
细节:处理完之后清除能够到达的节点节约历遍时间——测试用例存在一个全是7,只有最后节点为11,由此我加入
//这里清楚该相同数字的下标队列,因为已经访问完(不然会超时)
list.clear();
代码实现(空间应该还可以优化):
class Solution {
public int minJumps(int[] arr) {
int l=arr.length;
//保存每一个数字的多个下标,方便查询跳转
Map<Integer,List<Integer>> map=new HashMap<>();
//记录是否访问的数组,false表示未访问
boolean[] visited=new boolean[l];
//初始化统计,记录相同数字的下标,用《数字-下标链表》表示
for(int i=0;i<l;i++){
int mid=arr[i];
if(map.get(mid)==null){
List<Integer> list=new ArrayList<>();
list.add(i);
map.put(mid,list);
}
else{
map.get(mid).add(i);
}
}
//每次使用一个队列保存下一步能够到达的下标
//使用两个队列方便计算步骤
List<Integer> q1=new ArrayList<>();
List<Integer> q2=new ArrayList<>();
//初始点0
q1.add(0);
visited[0]=true;
int step=0;
if(l-1==0){
return 0;
}
while(true){
if(q1.size()!=0){
//q中保存当前步到达的点,历遍将下一步到达的点放入另一个q
for(int cur:q1){
//下标+1
if(cur+1<l&&!visited[cur+1]){
//判断是否是目标
if(cur+1==l-1){
return step+1;
}
q2.add(cur+1);
visited[cur+1]=true;
}
//下标-1
if(cur-1>0&&!visited[cur-1]){
//不可能为目标
q2.add(cur-1);
visited[cur-1]=true;
}
//相同数字跳转
List<Integer> list=map.get(arr[cur]);
for(int next:list){
if(next==l-1){
return step+1;
}
if(!visited[next]){
q2.add(next);
visited[next]=true;
}
}
//这里清楚该相同数字的下标队列,因为已经访问完(不然会超时)
list.clear();
}
q1.clear();
}
else{
//同上
for(int cur:q2){
if(cur==l-1){
return step;
}
if(cur+1<l&&!visited[cur+1]){
if(cur+1==l-1){
return step+1;
}
q1.add(cur+1);
visited[cur+1]=true;
}
if(cur-1>0&&!visited[cur-1]){
q1.add(cur-1);
visited[cur-1]=true;
}
List<Integer> list=map.get(arr[cur]);
for(int next:list){
if(next==l-1){
return step+1;
}
if(!visited[next]){
q1.add(next);
visited[next]=true;
}
}
list.clear();
}
q2.clear();
}
//步骤+1
step++;
}
}
}
结尾
题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems
⭐️关注作者,带你刷题,从简单的算法题了解最常用的算法技能(寒假每日一题)
⭐️关注作者刷题——简单到进阶,让你不知不觉成为无情的刷题机器,有问题请私信