1、题目说明:
输入一个所有元素都是自然数的数组,初始状态你的位置位于第1个元素,每个元素的位置表示1步,当前所在位置的元素数值表示你下一次前进能够移动的最大步数,你的目标是以最小的前进次数从数组的第一个元素移动到数组的最后一个元素位置,你需要输出每次前进的步数。
2、举例:
输入 : 2 3 1 1 4
输出 : 1 3
3、思路分析:
首先,我们通过分析题意,可以看出该题可以用贪心算法的思想来解。
思路:贪心算法
从第一个数开始, 寻找可以一个可以跳最远的点;
例1:3 1 2 4 1
1.从第一个位置0,可以跳到位置1和位置2和位置3;
2.如果跳到位置1,那么最远就可以跳到位置(1+1);
3.如果跳到位置2,那么最远就可以跳到位置(2+2);
4.如果跳到位置3,那么最远就可以跳到位置(3+4);
5.故选择跳到位置3 ,重复1.2.3步;
算法分析:
1.如果选择跳到位置3 ,就无法跳到位置2和位置3, 那么会不会因此错过最优解? 答:不会!
2.因为任意位置1和位置2能到达的位置, 位置3都可以到达;
3.故不会错过最优解;
4、代码实现(java语言)
package test;
import java.util.Scanner;
public class GreedyDemo{
public static void main(String[] args) {
//接受键盘输入
Scanner sc = new Scanner(System.in);
String num = sc.nextLine();
String[] numArray = num.split(" ");
int[] nums = new int[numArray.length];
//将输入类型转换成int
for(int i= 0 ;i< numArray.length ;i++) {
nums[i] = Integer.parseInt(numArray[i]);
}
//调用数组
getStep(nums);
}
public static void getStep(int[] nums){
//输入数组长度<=2,走一步完成
if(nums.length<=2){
System.out.println("1");
}
int n = nums.length;
int count = 0;
int left; //左边界 控制搜索的起始位置
int right; //右边界 控制搜索的终止位置
int[] result = new int[n];
for(int i = 0 ; i<n && nums[i]!= 0 ; count++) { //外层遍历数组元素
right = i + nums[i]; //最右
left = i + 1; //最左
for(int j= i+1 ;j< n && j<=i + nums[i] ;j++) {
if(j+nums[j] >= right){ //遍历可到达位置 能到达的最远位置
right = j+ nums[j]; //更新左右边界
left = j;
result[count]=j-i; //对于外层遍历的每一层,得到一个值放到result数组中
}
}
i = left; //左边界
}
for(int k=0; k<count-1;k++){
System.out.print(result[k]+" ");
}
}
}
5、测试演示:
输入:2 3 1 1 4
输出:1 3
本文算法思想参考:https://blog.csdn.net/qq_34594236/article/details/51601432 感谢作者!