自己的动态规划做法
dp[i]表示从i位置跳到最后一个位置需要的最少跳数;
base : dp[n-1] = 0, dp[n-2] = 1;
递归:dp[i] = min(dp[i+1], ... , dp[i+arr[i]]);
import java.util.*;
public class Main{
int cnt = 0;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
int cnt = getRes(arr, n);
System.out.println(cnt);
}
public static int getRes(int[] arr, int n) {
if (n <= 2) {
return 1;
}
int[] dp = new int[n];
dp[n-2] = 1;
for (int i = n - 3; i >= 0; i--) {
int val = arr[i];
if ((i + val + 1) >= n ) {
dp[i] = 1;
} else {
int min = Integer.MAX_VALUE;
for (int j = i + 1; j <= (i + val); j++) {
min = Math.min(min, dp[j]);
}
dp[i] = min + 1;
}
}
return dp[0];
}
}
左神的做法:时间复杂度O(N), 空间复杂度O(1)
public static int jump(int[] arr){
if(arr == null || arr.length == 0)
return 0;
int jump = 0; //跳数
int cur = 0; //当前位置
int next = 0; //当前所能到达的最远位置
for(int i = 0; i < arr.length; i++){
if(cur < i){
jump++;
cur = next;
}
next = Math.max(next, i + arr[i]);
}
return jump;
}
解题思路:
如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点。
可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新。
如果可以一直跳到最后,就成功了。
class Solution {
public boolean canJump(int[] nums) {
if (nums == null || nums.length == 0) return false;
int cur = nums[0];
int n = nums.length;
for (int i = 0; i < n; i++) {
if (i > cur) return false;
cur = Math.max(cur, i + nums[i]);
}
return true;
}
}
递归解法:
class Solution {
Set<Integer> set = new HashSet<>();
public boolean canReach(int[] arr, int start) {
if (start < 0 || start >= arr.length) return false;
if (set.contains(start)) return false;
else set.add(start);
if (arr[start] == 0) return true;
else return canReach(arr, start - arr[start]) || canReach(arr, start + arr[start]);
}
}
BFS解法:
class Solution {
public boolean canReach(int[] arr, int start) {
int n = arr.length;
Queue<Integer> queue = new ArrayDeque<>(n);
boolean[] vis = new boolean[n];
queue.add(start);
int index, l, r;
while (!queue.isEmpty()) {
index = queue.poll();
vis[index] = true;
if (arr[index] == 0) return true;
l = index - arr[index];
r = index + arr[index];
if (l >= 0 && !vis[l]) queue.add(l);
if (r < n && !vis[r]) queue.add(r);
}
return false;
}
}