2020-12-11 跳跃游戏 III LeetCode1306

362 阅读2分钟

题目详情

这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。

请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。

注意,不管是什么情况下,你都无法跳到数组之外。

力扣链接

leetcode-cn.com/problems/ju…

解题方法

方法一:广度优先搜索

我们可以使用广度优先搜索的方法得到从 start 开始能够到达的所有位置,如果其中某个位置对应的元素值为 0,那么就返回 True。

具体地,我们初始时将 start 加入队列。在每一次的搜索过程中,我们取出队首的节点 u,它可以到达的位置为 u + arr[u] 和 u - arr[u]。如果某个位置落在数组的下标范围 [0, len(arr)) 内,并且没有被搜索过,则将该位置加入队尾。只要我们搜索到一个对应元素值为 0 的位置,我们就返回 True。在搜索结束后,如果仍然没有找到符合要求的位置,我们就返回 False。

复杂度分析: 时间复杂度:O(N)O(N),其中 NN 是数组 arr 的长度。 空间复杂度:O(N)O(N)。

方法二:深度优先搜索

从起点开始用隐形递归栈深度优先搜索并且标记已经访问过的节点,如果任何一条路径遇到0就返回true,否则如果所有路径都没有0,返回false。

 * 跳跃游戏三
 * 这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。
 *
 * 请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。
 *
 * 注意,不管是什么情况下,你都无法跳到数组之外。
 *
 *  
 *
 * 示例 1:
 *
 * 输入:arr = [4,2,3,0,3,1,2], start = 5
 * 输出:true
 * 解释:
 * 到达值为 0 的下标 3 有以下可能方案:
 * 下标 5 -> 下标 4 -> 下标 1 -> 下标 3
 * 下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3
 *
 * 链接:https://leetcode-cn.com/problems/jump-game-iii
 */
public class JumpGameIII {

    // 深度优先遍历:递归
    public boolean canReachDFS(int[] arr, int start) {
        if (start < 0 || start >= arr.length || arr[start] == -1) {
            return false;
        }
        if (arr[start] == 0) {
            return true;
        }
        int temp = arr[start];
        arr[start] = -1;
        return canReachDFS(arr, start + temp) || canReachDFS(arr, start - temp);
    }

    public static void main(String[] args) {
        JumpGameIII jumpGameIII = new JumpGameIII();
        int[] arr = {4, 2, 3, 0, 3, 1, 2};
        System.out.println(jumpGameIII.canReachBFS(arr, 5));
    }

    // 广度优先遍历:循环
    public boolean canReachBFS(int[] arr, int start) {
        if (arr[start] == 0) {
            return true;
        }
        int length = arr.length;
        Queue<Integer> queue = new LinkedList();
        queue.offer(start);
        List<Integer> usedList = new ArrayList<>();
        usedList.add(start);
        while (!queue.isEmpty()) {
            Integer i = queue.poll();
            if (i + arr[i] < length && !usedList.contains(i + arr[i])) {
                if (arr[i + arr[i]] == 0) {
                    return true;
                }
                queue.offer(i + arr[i]);
                usedList.add(i + arr[i]);
            }
            if (i - arr[i] >= 0 && !usedList.contains(i - arr[i])) {
                if (arr[i - arr[i]] == 0) {
                    return true;
                }
                queue.offer(i - arr[i]);
                usedList.add(i - arr[i]);
            }
        }
        return false;
    }

}