Leedcode45----跳躍遊戲2
方案一:動規+逆向思維
class Solution{
//逆向思維
public int jump(int[] nums) {
int f[] = new int[nums.length];
f[nums.length-1] = 0;
for(int i=nums.length-2;i>=0;i--)
AddNew(f,nums,i);
return f[0];
}
//f[i]代表從從索引i到達最後需要的最少步數(dp),f[i]=-1代表其無法到達最後
void AddNew(int f[],int[] nums,int index)
{
int firstPosi = nums.length-1;
if(index+nums[index]<nums.length-1)
firstPosi = index+nums[index];
else
{
f[index]=1;
return;
}
for(int i=firstPosi;i>=index+1;i--)//只看f[index]到達的聊得地方
{
//該位置不可用
if(f[i]==-1)
continue;
//當f[index]=0時,此時不可以做最小比較,因爲做了還是0
//這個時候是初始時候
if(f[index]==0)
{
f[index] = f[i]+1;
}
else {
f[index]= java.lang.Math.min(f[index],f[i]+1);
}
}
//無法到達則改爲-1
if(f[index]==0)
f[index]=-1;
}
}
事實證明上面的代碼是正確的,但是複雜度太高
2.貪心
基本思路:f[i]表示從0到i所需要的最小1步數;f[i]的排列方式爲0 1 1 1 2 2 2 3 3 3 4 4 ...一直到最後一個位置
class Solution{
public int jump(int[] nums) {
//表示從f[i]表示從0到i的最小步數,其中f[0]=0
int[] f = new int[nums.length];
//i表示當前段的起點,表示終點
// 比如0爲一段,1 1 1又爲一段
int i=0,j=0,current=1;
int num = 0;//開始進入字段1的標記
while(j<nums.length-1)//表示後面還有要更新的位置
{
int max = 0;
for(int n = i;n<=j;n++)
{
max = java.lang.Math.max(max,n+nums[n]);
}
//獲取最大值後開始賦值,並更新i,j的值,並且要防止越界
if(max>nums.length-1)
max = nums.length-1;
num++;
i=j+1;
j=max;
}
return num;
}
}