/**
* @param {number[]} nums
* @return {number}
*/
var firstMissingPositive = function(nums) {
nums = nums || []
let i = 0
while (i < nums.length) {
const val = nums[i]
if (val > 0 && val <= nums.length && nums[val - 1] !== val) {
;[nums[val - 1], nums[i]] = [nums[i], nums[val - 1]]
} else {
i++
}
}
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== i + 1) {
return i + 1
}
}
return nums.length + 1
};
// 1. constant space -- in place, use original array
// 2. len is n, the first missing, must be within n, only unless it is n + 1
// 3. this swap a trick so you don't have to pull another loop. after swapping you don't move
// yet, you will process the just swapped element
/**
* @param {number[]} A
* @param {number} B
* @return {number[]}
*/
var cheapestJump = function(A, B) {
// !!! if the last place is -1, you cannot jump to that place !!
if (A == null || A.length === 0 || A[A.length - 1] === -1) {
return []
}
const len = A.length
const dp = A.map(() => ({cost: Infinity, next: -1}))
dp[len - 1] = {cost: 0, next: -1}
for (let i = len - 1; i > 0; i--) {
const {cost, next} = dp[i]
if (cost !== Infinity) { // can reach
for (let step = 1; step <= B && i - step >= 0; step++) {
const index = i - step
if (A[index] !== -1) {
const newCost = A[index] + cost
const node = dp[index]
if (newCost < node.cost || newCost === node.cost && node.next > i) {
node.cost = newCost
node.next = i
}
}
}
}
}
// console.log(dp)
if (dp[0].cost === Infinity) {
return []
} else {
let i = 0
const path = [0]
while (dp[i].next !== -1) {
path.push(dp[i].next)
i = dp[i].next
}
return path.map(el => el + 1) // !!! they index from 1 and they need the final path
}
};