Descrição do título
https://leetcode-cn.com/problems/jump-game/
solução
Pensando em usar dp para fazer isso, por que nosso array dp está definido?
- O que são variáveis? A cada salto, a posição alcançada é diferente, e o número de passos que podem ser saltados em cada posição também é diferente. Como definimos dp?
- Obviamente, usamos dp para expressar o número de passos que podem ser saltados em cada posição, então só podemos escolher a posição a ser alcançada, então dp [i] indica se o subscrito de 0 a i pode ser alcançado
- Pensando na recursão, o atual dp [i] depende se ele pode ser alcançado a partir da posição anterior. Precisamos manter uma variável para representar o subscrito máximo que pode ser alcançado no momento. Se o subscrito atual estiver dentro do máximo alcançável intervalo de subscrito dentro (porque você pode pular 1 etapa), é verdade, então atualize max
- O limite é dp [0] = verdadeiro;
- Escreva o código
class Solution {
public boolean canJump(int[] nums) {
boolean []dp = new boolean[nums.length];//表示从0到下标i的是否可以到达
dp[0]=true;
int max = 0+nums[0];//当前能抵达的最大下标
for(int i=1;i<nums.length;i++){
if(max>=i){
dp[i] = true;
if(nums[i]+i>max)
max = nums[i]+i;//更新能抵达的最大下标
}
//else dp[i] = false;//不能抵达
}
return dp[nums.length-1];
}
}
De acordo com o uso do dp, a complexidade do espaço pode ser otimizada:
class Solution {
public boolean canJump(int[] nums) {
//boolean []dp = new boolean[nums.length];//表示从0到下标i的是否可以到达
boolean res = true;//dp[0]等于true
int max = 0+nums[0];//当前能抵达的最大下标
for(int i=1;i<nums.length;i++){
if(max>=i){
res = true;
if(nums[i]+i>max)
max = nums[i]+i;//更新能抵达的最大下标
}else
res = false;
}
return res;
}
}
E se um algoritmo ganancioso for usado?
Pergunta de conversão: Até onde posso pular passando as regras de salto na pergunta? Se ele pode cruzar o último quadrado, retorna verdadeiro, caso contrário, retorna falso.
Portanto, podemos escrever o seguinte código ganancioso:
int n = nums.length;
int farthest = 0;
for (int i = 0; i < n - 1; i++) {
// 不断计算能跳到的最远距离
farthest = max(farthest, i + nums[i]);
// 可能碰到了 0,卡住跳不动了
if (farthest <= i) return false;
}
return farthest >= n - 1;
Descobrimos que é semelhante ao código acima, podemos pensar sobre a seguinte diferença entre programação gananciosa e dinâmica?