美文网首页
跳跃游戏

跳跃游戏

作者: 二进制的二哈 | 来源:发表于2019-12-10 22:24 被阅读0次

    题目来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/jump-game

    给定一个非负整数数组,你最初位于数组的第一个位置。

    数组中的每个元素代表你在该位置可以跳跃的最大长度。

    判断你是否能够到达最后一个位置。

    示例 1:

    输入: [2,3,1,1,4]
    输出: true
    解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
    

    示例 2:

    输入: [3,2,1,0,4]
    输出: false
    解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
    

    暴力解法,深度优先法,尝试每一种走法,适当剪枝,但是依然会超时

    class Solution {
    
        private static Map<Integer,Integer> book;
    
        public boolean canJump(int[] nums) {
            book = new HashMap<>();
            List<Integer> ans = new ArrayList<>();
            int maxStep = nums.length - 1;
            int curMaxStep = Math.min(nums[0],maxStep);
            dfs(nums,0,ans,curMaxStep);
            return ans.size() > 0;
        }
    
        private void dfs(int[] nums,int index,List<Integer> ans,int curMaxStep){
            if(index == nums.length -1 || ans.size() > 0){
                //到达终点
                ans.add(1);
                return;
            }
            int val = nums[index];
            //尝试可以跳跃的每一步
            int maxStep = nums.length - 1 - index;
            int canJumpStep = Math.min(val,maxStep);
    
            //如果当前可以跳的最远距离都比之前跳过的最大距离短,就不用尝试了
            if (index + canJumpStep < curMaxStep){
                return;
            }else{
                curMaxStep = index + canJumpStep;
            }
    
            for(int i=canJumpStep;i>0;i--){
                //下一步的坐标
                int nextStep = index+i;
                if(book.get(nextStep) != null || nextStep > nums.length)
                    continue;
                //标记这步已经尝试过了
                book.put(nextStep,1);
                dfs(nums,nextStep,ans,curMaxStep);
                if(ans.size() > 0)
                    return;
            }
        }
    }
    

    第二种解法:
    思路:将0看做是沼泽地,如果0左边的数跳不过去,说明这个数相当于一个陷阱,那就索性将这个数也置为0,这样一直向左走。

    class Solution {
    
        public boolean canJump(int[] nums) {
            int len = nums.length;
            //先判断一些特殊值
            if(len == 0 || len == 1) return true;
            if(len == 2) return nums[0] > 0;
            if(nums[0] == 0) return false;
    
            int right = len-3;
            int maxZeroIndex = -1;
            while(right >= 0){
                int cur = nums[right];
                if(cur > 0){
                    //当前数大于0
                    //判断右边是不是0
                    if(nums[right+1] == 0){
                        //右边的数是0
                        if(maxZeroIndex == -1)
                            maxZeroIndex = right+1;
                        //判断当前这个数跳最远能不能跳出最右边的0
                        int target = cur + right;
                        if(target > maxZeroIndex){
                            //说明能跳出最远的0
                            maxZeroIndex = -1;
                        }else{
                            //跳不出去,将当前值置为0
                            nums[right] = 0;
                        }
                    }
                }else{
                    //当前数等于0
                    if(maxZeroIndex == -1)
                        maxZeroIndex = right;
                }
                right--;
            }
            if(maxZeroIndex == -1)
                return true;
            return false;
        }
    
    }
    

    贪心算法:

    class Solution {
    
        public boolean canJump(int[] nums) {
            int last = nums.length-1;
            for(int i = last;i>=0;i--){
                if(nums[i]+i >= last){
                    last = i;
                }
            }
            return last==0;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:跳跃游戏

          本文链接:https://www.haomeiwen.com/subject/esjngctx.html