题目:
题目思路:
两种方法:
(1)动态规划法
把所有的可能性展开
进行递归
1.设置一个表格一开始除终点外都设置为0(未知) 1为通 -1为不通
2.当一个点被判定为不通点时,把它设为-1,并看前一个点是否只有唯一路径,是的话,也把前面的点设置为-1,以此类推
3.当一条通路,走到终点时如例子的3->2->4,则都把他们设置成1(通)
代码:
/**
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function(nums) {
let totalLenght=nums.length;
const memo=Array(totalLenght).fill(0);
memo[totalLenght-1]=1;
function jump(position)
{
if(memo[position]===1)
{
return true;
}
else if(memo[position]===-1)
{
return false;
}
const maxJump=Math.min(position+nums[position],totalLenght-1);
for(let i=position+1;i<=maxJump;i++)
{
const jumpResult=jump(i);
if(jumpResult===true)
{
memo[position]=1;
return true;
}
}
memo[position]=-1;
return false;
}
let result=jump(0);
return result;
};
(2)动态规划反向进行遍历(top-down),反向推,不需要进行递归
((2))4节点为终点,则看前一个点,可以最大走两部所以可以到达终点,并设置成1
((0))最大步数为0,无法走向标记为1的点,设置为-1;
((1))最大可走1步,无法走到标记为1的点所以设置为-1
((3))最大可走3步,可以走到(2)标记为1的点.所以把它也设置成1此时,(3)为起点所以判断为true,如果(3)设置为-1则判断为false;
代码:
/**
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function(nums) {
let totalLenght=nums.length;
const memo=Array(totalLenght).fill(0);
memo[totalLenght-1]=1;
for(let i=totalLenght-2;i>=0;i--)
{
const maxJump=Math.min(nums[i]+i,totalLenght-1);
for(let j=i;j<=maxJump;j++)
{
if(memo[j]===1)
{
memo[i]=1;
break;
}
}
if(memo[i]===0)
{
memo[i]=-1;
}
}
if(memo[0]===1)
{
return true;
}
else if(memo[0]===-1)
{
return false;
}
};
结果:
可以看出动态规划的遍历和递归的for循环颇多往往会使运行效率低
(3)贪心算法(非常的简单)
不需要建立数组对象
只需要设置变量maxJump
maxJump一开始设置为终点的索引值,
例子所示为maxJump=4;
然后从后向前遍历
到(3:2)节点,因为索引值为3最大步数为2,所以3+2>=4=maxJump所以可以到终点,然后maxJump=3;
到(2:0)节点,2+0<=3;所以maxJump不变
到(1:1)节点,1+1<=3;所以maxJump不变
到(0:3)节点,0+3<=3;所以maxJump=0;
输出true
可见
循环结束
如果maxJump!=0则输出false;
代码:
/**
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function(nums) {
let totalLenght=nums.length;
let maxJump=totalLenght-1;
for(let i=totalLenght-2;i>=0;i--)
{
if(nums[i]+i>=maxJump)
{
maxJump=i;
}
}
if(maxJump===0)
{
return true;
}
else
{
return false;
}
};
结果:运行效率提高