[Leetcode学习-java]Jump Game I~III

问题:Jump Game I

难度:medium

说明:

给出一个 数组,数组内 数字 表示可以往前跳 0 ~ N 格, 如果能够跳到终点就返回 true,不能 false。

题目连接:https://leetcode.com/problems/jump-game/

输入范围:

  • 1 <= nums.length <= 3 * 10^4
  • 0 <= nums[i][j] <= 10^5

输入案例:

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.
 

我的代码:

这个我处理起来就随便点了,因为可以跳 0 ~ N 格,那我每次都跳一格,然后发现了 0 ,就马上回退,看看那个地方可以跳过 0 这个坑就行了。其实还可以优化,不用重复计算。

class Solution {
    public boolean canJump(int[] nums) {
        int len = nums.length, len1 = len - 1;
        A:for(int i = 0;i < len;i ++) 
            if(nums[i] == 0 && i != len1) {
                for(int j = i;j -- > 0;) // 发现坑,就马上回跳
                    if(nums[j] > i - j) continue A;
                return false; // 如果会跳没找到一个适合的就退出
            }
        return true;
    }
}

问题:Jump Game II

难度:hard

说明:

给出一个 数组,数组内 数字 表示可以往前跳 1 ~ N 格, 假设一定会跳到终点, 求跳跃的最少次数。

题目连接:https://leetcode.com/problems/jump-game-ii/

输入范围:

  • 1 <= nums.length <= 3 * 104
  • 0 <= nums[i] <= 105

输入案例:

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

我的代码:

有点难度,不过如果学过 KMP 的话,前缀函数的思想应该可以解决,如果用 全排列,把 1 ~ num[i] 情况用 dfs (递归 + 遍历)都处理一遍,这种阶乘的时钟周期绝对超时,但是如果想到 前缀函数,就是使用分治法,避免重复计算,并且利用前一个已经得出最短路径结果再进行一次计算,可能会很简单。

1、用一个 jump 存放 跳跃索引。

2、从尾部开始遍历,从尾部找到最长可跳跃到达的索引,然后存放。

3、如果找到可跳跃索引 == jump[j],就存放 jump[j],否则存放最长跳跃索引 j。 

class Solution {
    public int jump(int[] nums) {
        int len = nums.length;
        int[] jump = new int[len];
        jump[len - 1] = len - 1;
        for(int i = len - 1; i -- > 0;) { // 思路类似于前缀索引
            int j = i + 1;
            int temp = nums[i] + i;
            while(j < len && temp > jump[j ++]); // 利用前一次结果, 找出更少的一步
            j --; // 每次都会多出 1
            if(temp == jump[j]) jump[i] = jump[j]; // 结果如果和 jump 的索引一致,先使用索引
            else jump[i] = j; // 否则使用 j
        }

        int begin = 0, times = 0;
        while(true) { // 无非再跳一次
            if(begin == len - 1) break;
            begin = jump[begin];
            times ++;
        }
        return times;
    }
}

问题:Jump Game III

难度:medium

说明:

给出一个 数组,和开始索引,从开始索引出发,能够左跳或者右跳,如果能够移动到数组内数值为 0 的位置,就返回true,否则返回 false。

题目连接:https://leetcode.com/problems/jump-game-iii/

输入范围:

  • 1 <= arr.length <= 5 * 10^4
  • 0 <= arr[i] < arr.length
  • 0 <= start < arr.length

输入案例:

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.

我的代码:

这个跟全排列一个意思,然后我来个缓存 cacheMap,防止重复计算就行。

class Solution {
    private HashMap<Integer, Boolean> cache = new HashMap<>(); // 缓存
    public boolean canReach(int[] arr, int start) {
        return recurtion(arr, start, arr.length, new boolean[arr.length]);
    }
    
    public boolean recurtion(int[] arr, int start, int len, boolean[] visited) {
        if(start >= 0 && start < arr.length && !visited[start]) {
            visited[start] = true; // 避免跳重复了
            boolean reach = arr[start] == 0  // 查看是否到达了 0
                || cache.getOrDefault(start, false)  // 防止重复计算
                || recurtion(arr, start + arr[start], len, visited) // 左跳
                || recurtion(arr, start - arr[start], len, visited); // 右跳
            visited[start] = false;
            cache.put(start, reach);
            return reach;
        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_28033719/article/details/110378502