层次遍历、递归:jump-game

本文介绍了一种名为“跳跃游戏”的算法问题,通过三种方法探讨如何判断能否从数组的起始位置到达最后一个元素。方法一使用贪心算法,方法二采用类似层次遍历的方式,而方法三则利用递归来解决问题,并通过实例演示了每种方法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A =[2,3,1,1,4], returntrue.
A =[3,2,1,0,4], returnfalse.

析:每次从某位置可以左右跳,跳的步数<=A[i]
法1:贪心法,略,参考网友的

法2:类似层次遍历求法。
比如第一次只有末尾的下标7,下次判断能从7传到的下标为3、5,下次再从下标3、5再传递一个层次,最后判断0是否在不满足的集合中。

public boolean canJump(int[] A) {
        if(A.length==0 || A.length==1)
            return true;
        // 放的是下标
        Set<Integer> oldSet = new HashSet<>();
        Set<Integer> newSet = new HashSet<>();
        // 不能跳到末尾的点
        Set<Integer> noOldSet = new HashSet<>();
        Set<Integer> noNewSet = new HashSet<>();
        newSet.add(A.length-1);
        for(int i=0;i<A.length-1;i++)
            noNewSet.add(i);
        while(newSet.size()!=0){
            oldSet.clear();
            oldSet.addAll(newSet);
            newSet.clear();

            noOldSet.clear();
            noOldSet.addAll(noNewSet);
            for(int no:noOldSet)
                for(int y:oldSet){
                    // 距离<=最大步数
                    if(Math.abs(no-y)<=A[no]){
                        noNewSet.remove(no);
                        newSet.add(no);
                        // 出现了下标0
                        if(no==0)
                            return true;
                    }

                }
        }
        return false;
    }

法3:用递归写,注意为了递归停止,必须用集合保存已经访问过的位置

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc= new Scanner(System.in);
        Main main = new Main();
        int[] A1= {2,3,1,1,4};
        int[] A2={1,1,0,1};
        System.out.println(main.canJump(A1));
        System.out.println(main.canJump(A2));


    }

    public boolean canJump(int[] A) {
        if(A.length==0 || A.length==1)
            return true;
        Set<Integer> set = new HashSet<>();
        return canJump(A,0,set);
    }
    // set里放已经考虑过的位置,考虑过的就不用重复考虑了,用来栈的停止
    public boolean canJump(int[] A,int startIndex,Set<Integer> set) {
        //Set<Integer> set = new HashSet<>();
        if(startIndex>=A.length-1)
            return true;
        else if(startIndex<0)
            return false;
        else {
            if(!set.contains(startIndex))
            {
                set.add(startIndex);
                if(A[startIndex]==0)
                    return false;
                else {
                    for(int step=1;step<=A[startIndex];step++){
                        if(canJump(A,startIndex+step,set) || canJump(A,startIndex-step,set))
                            return true;
                    }
                    return false;
                }

            }
            else {
                return false;
            }

        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值