55. Jump Game
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
个人解法:
理解题意,其实能否跳到终点取决于是否有跨不过去的0点,除此以外所有的点哪怕再慢也能把你带到终点。
所以思路就是遍历所有的零点,判断它是否能被跳过。
/**
* 55. Jump Game
* @param {number[]} nums
* @return {boolean}
*/
var canJump = function (nums) {
if (nums.length <= 1) {
return true;
}
let zeroList = [];
for (let i = 0; i < nums.length; i++) {
if (nums[i]) {
continue;
}
zeroList.push(i);
}
for (let i = 0; i < zeroList.length; i++) {
let start = -1
let end = zeroList[i];
let flag = false;
for (let j = end - 1; j > start; j--) {
if (i === zeroList.length - 1 && nums[nums.length - 1] === 0) {
if (end - j <= nums[j]) {
flag = true;
break;
}
} else {
if (end - j < nums[j]) {
flag = true;
break;
}
}
}
if (!flag)
return false;
}
return true;
};
一开始我觉得下面那个解法我觉得比上面那个好点,跑出来却比上一个慢10%左右。
这个算法总体思路相似,差异点在于从最后一个零点开始,取到第一个可以超过或到达该零点的点,跳过中途所有的零点,直接取到上一次取到的点的上一个零点。
感觉上是会快,但是这个算法只是在理想情况下快很多,达到接近O(n)的复杂度,而且这个O(n)实际上远远快于上一个O(n),在最差情况则几乎是O(n^2)的复杂度,所以综合跑下来差不多但是略慢。
// alternative solution;
var canJump = function (nums) {
if (nums.length <= 1) {
return true;
}
let zeroList = [];
for (let i = 0; i < nums.length; i++) {
if (nums[i]) {
continue;
}
if (i)
zeroList.push(i);
else
return false;
}
for (let i = zeroList.length - 1; i >= 0; i--) {
for (let j = 0; j < zeroList[i]; j++) {
if (i === zeroList.length - 1 && nums[nums.length - 1] === 0) {
if (zeroList[i] - j <= nums[j]) {
i = zeroList.findIndex(x => x > j);
break;
}
} else {
if (zeroList[i] - j < nums[j]) {
i = zeroList.findIndex(x => x > j);
break;
}
}
if (j === zeroList[i] - 1) {
return false;
}
}
}
return true;
};