LeetCode 55. 跳躍遊戲 ( 回溯 dp 貪心

RedemptionC發表於2020-10-01

這個題位元組一面做過 不過當時沒想到好的解法

首先能寫出一個回溯的搜尋演算法:

class Solution {
    private boolean[] vis;
    private boolean dfs(int[] nums,int cur){
        if(cur==nums.length-1){
            return true;
        }
        boolean rs=false;
        vis[cur]=true;
        for(int i=1;i<=nums[cur];i++){
            // 向右/向左
            // ? 指正,這裡是不需要向左跳的,不過即使如此也過不了qaq
            if(cur+i<nums.length&&!vis[cur+i]){
                vis[cur+i]=true;
                rs=rs||dfs(nums,cur+i);
                vis[cur+i]=false;
            }
        }
        return rs;
    } 
    public boolean canJump(int[] nums) {
        vis=new boolean[nums.length];
        return dfs(nums,0);
    }
}

超時

突然想到這個題很適合用dp來做:

class Solution {
    public boolean canJump(int[] nums) {
        // dp[i]表示從第i個位置出發,能否到達終點
        // 遞推公式:dp[i]=dp[i+1] || dp[i+2] || ... || dp[i+nums[i]]
        boolean[] dp=new boolean[nums.length];
        dp[dp.length-1]=true;
        for(int i=dp.length-2;i>=0;i--){
            // 從當前點,判斷所有他能到達的點,看能否到達
            for(int j=1;j<=nums[i];j++){
                if(dp[i+j]){
                    dp[i]=true;
                    break;
                }
            }
        }
        return dp[0];
    }
}

雖然挺慢的

最妙的還是這個(,雖然不是不能馬上想到,這個題dp應該是能馬上想到的

class Solution {
    public boolean canJump(int[] nums) {
        // reach表示能通過跳躍到達的最遠位置
        int reach=0;
        for(int i=0;i<nums.length;i++){
            if(i>reach){
                // 當前遍歷到的位置,是不能通過跳躍到達的
                // 那麼自然也到不了終點
                return false;
            }
            reach=Math.max(reach,nums[i]+i);
        }
        // 上述迴圈走完,說明對於終點,也是可以通過跳躍到達
        return true;
    }
}

 

相關文章