78、贪心-跳跃游戏

思路

方法1: canJump01 - 使用递归(回溯法)

这个方法是通过递归实现的,它从数组的第一个位置开始,尝试所有可能的跳跃步数,直到达到数组的最后一个位置或遍历完所有的可能性。

思路:

  • 如果数组为空或者长度为0,直接返回 false。
  • 从数组的第一个位置(index = 0)开始调用递归函数 process。
  • 递归的终止条件是,如果当前的 index 等于 N-1(数组的最后一个位置),则返回 true。
  • 在当前位置,根据该位置的数字决定可以跳跃的步数范围,递归地尝试每一种跳跃步数。
  • 如果任何一种跳跃方式可以到达最后位置,则返回 true。

缺点:

  • 这种方法的时间复杂度非常高,因为它尝试了所有可能的路径,可能导致指数级的计算量。

方法2: canJump02 - 使用动态规划

这个方法使用了动态规划(DP)来减少重复计算,提高效率。

思路:

  • 初始化一个布尔型的数组 dp,其中 dp[i] 表示是否可以从起始位置跳跃到位置 i。
  • dp[0] 初始化为 true,因为起始位置总是可达的。
  • 从 i = 1 开始遍历数组,对于每个位置 i,检查所有之前的位置 j,看是否存在一个 j,使得从 j 跳跃到 i 是可行的(即 dp[j] 为 true 且 j + nums[j] 大于等于 i)。
  • 如果找到这样的 j,则设置 dp[i] = true 并中断当前循环。

优点:

  • 时间复杂度为 O(n^2),空间复杂度为 O(n)。

方法3: canJump - 贪心算法

使用贪心算法解决问题,思路更为直接和高效。

思路:

  • 维护一个变量 maxReach 来存储从起点开始可达的最远位置。
  • 遍历数组,对于每个位置 i,首先检查 i 是否超过了之前的 maxReach。如果超过,则说明无法到达当前位置,返回 false。
  • 然后更新 maxReach 为 max(maxReach, i + nums[i])。
  • 如果在任何时刻 maxReach 大于等于数组的最后位置,直接返回 true。

优点:

  • 时间复杂度为 O(n),空间复杂度为 O(1),是三种方法中最优的。

代码如下:

java 复制代码
class Solution {
   public boolean canJump01(int[] nums) {
        if (nums==null||nums.length==0){
            return false;
        }
        return process(nums,0,nums.length);
    }

    private boolean process(int[] nums, int index, int N) {
        if (index==N-1){
            return true;
        }
        int num=nums[index];
        boolean ans=false;
        //当前节点跳 1-num 步
        for (int i = 1; i <=num; i++) {
            ans=ans||process(nums,index+i,N);
        }
        return ans;
    }


    public boolean canJump02(int[] nums){
        if (nums==null||nums.length==0){
            return false;
        }
        int N=nums.length;
        boolean[] dp = new boolean[N];
        dp[0] = true; // 起点是可达的
        for (int i = 1; i < nums.length; i++) {
            // 初始化当前位置为不可达
            dp[i] = false;
            // 遍历到当前位置之前的所有位置
            for (int j = 0; j < i; j++) {
                // 如果位置 j 可达,并且从 j 跳跃足够远以到达 i
                if (dp[j] && j + nums[j] >= i) {
                    dp[i] = true;
                    break; // 找到一个可达的位置后,无需继续检查
                }
            }
        }
        return dp[N-1];
    }

     //假设从 0 跳 最远跳到i位置 那说明 0-i都是可达的,所以只需要关心每次跳多远即可
    //然后再次从1 位置尝试跳最远  如果1 >max 说明在0位置跳的时候无法跳到1
    public boolean canJump(int[] nums) {
        int maxReach = 0; // 可达的最远位置
        for (int i = 0; i < nums.length; i++) {
            // 如果当前位置超过了最远可达位置,则无法继续
            if (i > maxReach) {
                return false;
            }
            // 更新最远可达位置
            maxReach = Math.max(maxReach, i + nums[i]);
            // 如果最远可达位置已经超过或到达数组的最后一个位置
            if (maxReach >= nums.length - 1) {
                return true;
            }
        }
        // 结束循环后,如果还没返回true,则说明最后位置不可达
        return false;
    }
}
相关推荐
.Bryce.24 分钟前
你了解 Blackboard(黑板系统)吗?听说过基于黑板系统实现的智能体吗?
java·网络·gpt·php·agent·codex·黑板系统
猿究院_夏燊7 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog8 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
inrichtt8 小时前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
信誓旦旦的程序猿8 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河8 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
Jlzn88888 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造
HPtiger8 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训9 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
河南花仙子科技9 小时前
古镇非遗小游戏如何传播传统文化
游戏