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 感謝作者!