1345. 跳跃游戏 IV
广度优先搜索
class Solution(object):
def minJumps(self, arr):
"""
:type arr: List[int]
:rtype: int
"""
# 先得到一个值-下标字典
import collections
maps = collections.defaultdict(list)
for i in range(len(arr)):
if arr[i] not in maps:
maps[arr[i]] = [i]
else:
maps[arr[i]].append(i)
visited = [False for _ in range(len(arr))]
from collections import deque
deque=deque()
deque.append((0,0))
while deque:
cur_index,step=deque.popleft()
cur_value=arr[cur_index]
#终止条件
if cur_index==len(arr)-1:
return step
#向前/向后/等值
if cur_index+1<len(arr) and visited[cur_index+1]==False:
deque.append((cur_index+1,step+1))
visited[cur_index + 1]=True
if cur_index-1>=0 and visited[cur_index-1]==False:
deque.append((cur_index-1,step+1))
visited[cur_index- 1] = True
other_cur_same=maps[cur_value]
other_cur_index=[]
for i in other_cur_same:
if i != cur_index:
other_cur_index.append(i)
for j in other_cur_index:
if visited[j]==False:
deque.append((j,step+1))
visited[j] = True
del maps[cur_value]
class Solution {
public:
int minJumps(vector<int>& arr) {
int n = arr.size();
unordered_map<int, vector<int>> num2ids;
for (int i = 0; i < n; ++i)
{
num2ids[arr[i]].push_back(i);
}
// 这里对应的是arr里的序号
bool isVisited[n];
memset(isVisited, 0, sizeof(isVisited));
// 插入编号
queue<int> q;
q.push(0);
isVisited[0] = true;
int steps = 0;
while (!q.empty())
{
for (int i = q.size(); i > 0; --i)
{
int curr = q.front();
q.pop();
if (curr == n-1)
{
return steps;
}
if (curr-1 >= 0 && !isVisited[curr-1])
{
q.push(curr-1);
isVisited[curr-1] = true;
}
if (curr+1 < n && !isVisited[curr+1])
{
q.push(curr+1);
isVisited[curr+1] = true;
}
if (num2ids.find(arr[curr]) != num2ids.end())
{
vector<int>& nexts = num2ids[arr[curr]];
for (int j = nexts.size()-1; j >= 0; --j)
{
int next = nexts[j];
if (!isVisited[next])
{
q.push(next);
isVisited[next] = true;
}
}
// 非常重要的步骤记得要删除,否则会超时
num2ids.erase(arr[curr]);
}
}
// 到下一层
++steps;
}
return -1;
}
};
作者:ffreturn
链接:https://leetcode-cn.com/problems/jump-game-iv/solution/1345-cjian-dan-yi-dong-de-yan-du-you-xia-qtmk/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
深度优先搜索
树的最短路径:这个思路是错的!!
class Solution:
def minJumps(self, arr: List[int]) -> int:
#先得到一个值-下标字典
import collections
maps=collections.defaultdict(list)
for i in range(len(arr)):
if arr[i] not in maps:
maps[arr[i]]=[i]
else:
maps[arr[i]].append(i)
#深搜,树的最短深度。
def dfs(index):
visited[index]=True
#返回
if index==len(arr)-1:
return 0
cur=arr[index]
other_cur_index=[]
other_cur_same=maps[cur]
for i in other_cur_same:
if i!= index:
other_cur_index.append(i)
#前后
a1=0
a2=0
if index-1>=0 and visited[index-1]==False:
visited[index-1]=True
a1=1+dfs(index-1)
if index+1<=len(arr)-1 and visited[index+1]==False:
visited[index+1]=True
a2=1+dfs(index+1)
#等值
a3=0
if len(other_cur_index)>0:
for j in other_cur_index:
if visited[j]==False:
visited[j]=True
a3=1+dfs(j)
#无法判断a3为0的时候,其他两个还有值的情况。所以找的不是最小树深。
cur_ans=0
for a in [a1,a2,a3]:
if a>0:
cur_ans=a
for a in [a1,a2,a3]:
if a>0:
cur_ans=min(cur_ans,a)
# cur_ans=min(a1,a2,a3)
# visited[index]=Truee
return cur_ans
visited=[False for _ in range(len(arr))]
return dfs(0)
45 跳跃游戏
贪心
贪心,但是有的case不通过
如下
class Solution:
def jump(self, nums: List[int]) -> int:
#极端情况
if len(nums)==1:
if nums[0]!=0:
return 0
#贪心,每次都找最大的地方跳
cur_index=0
cur_value=nums[cur_index]
ans=0
while cur_index<len(nums):
max_jump_step=cur_value
if max_jump_step==0:
return 0
next_value_max=0
next_index_max=0
for i in range(cur_index+1,cur_index+max_jump_step+1):
#判断是否能到达最后一个位置
if i==len(nums)-1:
return ans+1
if nums[i]>=next_value_max:
next_value_max=nums[i]
next_index_max=i
cur_value=next_value_max
cur_index=next_index_max
ans=ans+1
正确的解法
class Solution:
def jump(self, nums: List[int]) -> int:
#找当前位置,能跳的位置的最大位置,比如起点是2,可跳范围是3,1;跳到3之后再跳的最大位置。
#极端情况
if len(nums)==1:
if nums[0]!=0:
return 0
#贪心,每次都找最大的地方跳
cur_index=0
cur_value=nums[cur_index]
ans=0
while cur_index<len(nums):
max_jump_step=cur_value
if max_jump_step==0:
return 0
next_index_max=0
for i in range(cur_index+1,cur_index+max_jump_step+1):
#判断是否能到达最后一个位置
if i==len(nums)-1:
return ans+1
#位置i能到达的最大位置
next_value=nums[i]
next_index=i
next_index_all=next_value+next_index
if next_index_all>=next_index_max:
next_index_max=next_index_all
cur_value=next_value
cur_index=next_index
ans+=1
1340. 跳跃游戏 V
记忆化搜索
class Solution:
def maxJumps(self, arr: List[int], d: int) -> int:
@lru_cache(None)
def dfs(i):
left = max(0, i - d)
right = min(len(arr) - 1, i + d)
#往左边跳
cur_max=1
for k in range(i-1,left-1,-1):
if arr[i]>arr[k]:
cur_max=max(cur_max,dfs(k)+1)
else:
break
#往右边跳
for k in range(i+1,right+1):
if arr[i]>arr[k]:
cur_max=max(cur_max,dfs(k)+1)
else:
break
return cur_max
res=0
for h in range(len(arr)):
cur=dfs(h)
res=max(res,cur)
return res