jump game 系列 55, 45, 1306, 1345
You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.
Return true if you can reach the last index, or false otherwise.
Example 1:
Input: nums = [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Example 2:
Input: nums = [3,2,1,0,4] Output: false Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
Constraints:
1 <= nums.length <= 1040 <= nums[i] <= 105
解法一:greedy
class Solution { public boolean canJump(int[] nums) { int farthest = 0; for(int i=0;i<nums.length;i++){ if(i>farthest) return false; farthest = Math.max(farthest,i+nums[i]); } return farthest>=nums.length-1;//坑点:到达最后一个元素即可,所以这个地方是len-1 !!! } }
解法二:dfs
这个解法会超时,因为时间复杂度为O(xn)
class Solution { public boolean canJump(int[] nums) { return helper(nums,0); } private boolean helper(int[] nums,int pos){ if(pos>=nums.length-1) return true; for(int i=pos+1;i<=pos+nums[pos];i++){ if(helper(nums,i)) return true; } return false; } }
我们可以增加memoization,对其进行优化,同样的位置算一次后不再重新计算
class Solution { public boolean canJump(int[] nums) { int[] mem = new int[nums.length]; return helper(nums,0,mem); } private boolean helper(int[] nums,int pos,int[] mem){ if(pos>=nums.length-1) return true; if(mem[pos]<0) return false; for(int i=pos+1;i<=pos+nums[pos];i++){ if(helper(nums,i,mem)) return true; } mem[pos]=-1; return false; } }
时间复杂度:O(XN) X为nums[i], N为nums的长度
Given an array of non-negative integers nums, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
You can assume that you can always reach the last index.
Example 1:
Input: nums = [2,3,1,1,4] Output: 2 Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
Example 2:
Input: nums = [2,3,0,1,4] Output: 2
Constraints:
1 <= nums.length <= 1040 <= nums[i] <= 1000
解法:我们可以使用bfs,将每次可以到达的点都放到队列中,
解法一:bfs
class Solution { public int jump(int[] nums) { boolean[] visited = new boolean[nums.length]; Queue<Integer> queue = new LinkedList(); if(nums.length==1) return 0; queue.offer(0); visited[0] = true; int step = 1; while(!queue.isEmpty()){ int size = queue.size(); for(int i=0;i<size;i++){ int curr = queue.poll(); for(int j = curr+1;j <= Math.min(curr+nums[curr], nums.length-1);j++){ if(j==nums.length-1) return step; if(visited[j]) continue; queue.offer(j); visited[j]=true; } } step++; } return -1; } }
解法二:优化的bfs,实际上我们不需要将所有元素记录到队列中,我们只需要维护一对下一段可达的start和end,然后每层遍历时将可到到的farthest位置记录下来
class Solution { public int jump(int[] nums) { int start = 0,end = 0, step = 0, farthest = 0; while(start < nums.length){ for(int i = start; i <= end; i++){ if(i == nums.length-1) return step; farthest = Math.max(farthest, i + nums[i]); } start = end+1; end = Math.min(farthest, nums.length-1); step++; } return -1; } }
Given an array of non-negative integers arr, you are initially positioned at start index of the array. When you are at index i, you can jump to i + arr[i] or i - arr[i], check if you can reach to any index with value 0.
Notice that you can not jump outside of the array at any time.
Example 1:
Input: arr = [4,2,3,0,3,1,2], start = 5 Output: true Explanation: All possible ways to reach at index 3 with value 0 are: index 5 -> index 4 -> index 1 -> index 3 index 5 -> index 6 -> index 4 -> index 1 -> index 3
Example 2:
Input: arr = [4,2,3,0,3,1,2], start = 0 Output: true Explanation: One possible way to reach at index 3 with value 0 is: index 0 -> index 4 -> index 1 -> index 3
Example 3:
Input: arr = [3,0,2,1,2], start = 2 Output: false Explanation: There is no way to reach at index 1 with value 0.
Constraints:
1 <= arr.length <= 5 * 1040 <= arr[i] < arr.length0 <= start < arr.length
解法:bfs
class Solution { public boolean canReach(int[] arr, int start) { if(arr[start]==0) return true; Queue<Integer> queue = new LinkedList(); boolean[] visited = new boolean[arr.length]; visited[start]=true; queue.offer(start); while(!queue.isEmpty()){ int pos = queue.poll(); if( pos+arr[pos]<arr.length && !visited[pos+arr[pos]]){ if( arr[pos+arr[pos]] ==0 ) return true; queue.offer(pos+arr[pos]); visited[pos+arr[pos]]=true; } if(pos-arr[pos]>=0 && !visited[pos-arr[pos]]){ if( arr[pos-arr[pos]] ==0 ) return true; queue.offer(pos-arr[pos]); visited[pos-arr[pos]]=true; } } return false; } }
Given an array of integers arr, you are initially positioned at the first index of the array.
In one step you can jump from index i to index:
i + 1where:i + 1 < arr.length.i - 1where:i - 1 >= 0.jwhere:arr[i] == arr[j]andi != j.
Return the minimum number of steps to reach the last index of the array.
Notice that you can not jump outside of the array at any time.
Example 1:
Input: arr = [100,-23,-23,404,100,23,23,23,3,404] Output: 3 Explanation: You need three jumps from index 0 --> 4 --> 3 --> 9. Note that index 9 is the last index of the array.
Example 2:
Input: arr = [7] Output: 0 Explanation: Start index is the last index. You do not need to jump.
Example 3:
Input: arr = [7,6,9,6,9,6,9,7] Output: 1 Explanation: You can jump directly from index 0 to index 7 which is last index of the array.
Constraints:
1 <= arr.length <= 5 * 104-108 <= arr[i] <= 108
解法:跟上面的题类似, 只是多增加了一种跳法,就是可以跳到跟当前值一样的位置
因此只需要增加一个hashmap来记录每个value对应的pos,然后bfs遍历下一个位置的时候加上跳到相同值的位置 逻辑即可
class Solution { public int minJumps(int[] arr) { Map<Integer, List<Integer>> map = new HashMap(); for(int i = 0;i < arr.length;i++){ List<Integer> list = map.getOrDefault(arr[i], new ArrayList()); list.add(i); map.put(arr[i], list); } Queue<Integer> queue = new LinkedList(); Set<Integer> visited = new HashSet(); int step = 0; queue.offer(0); visited.add(0); while(!queue.isEmpty()){ int size = queue.size(); for(int i=0;i<size;i++){ int curr = queue.poll(); if(curr == arr.length-1) return step; if(curr - 1 >= 0 && !visited.contains(curr -1)){ visited.add(curr - 1); queue.offer(curr - 1); } if(curr + 1 < arr.length){ visited.add(curr + 1); queue.offer(curr + 1); } List<Integer> others = map.getOrDefault(arr[curr], List.of()); for(Integer other:others){ if(visited.add(other)){ queue.offer(other); } } others.clear();//遍历完的一定要进行清理,避免再次遍历导致超时 } step++; } return step; } }

浙公网安备 33010602011771号