|
| 1 | +/** |
| 2 | + * DYNAMIC PROGRAMMING BOTTOM-UP approach of solving Jump Game. |
| 3 | + * |
| 4 | + * This comes out as an optimisation of DYNAMIC PROGRAMMING TOP-DOWN approach. |
| 5 | + * |
| 6 | + * The observation to make here is that we only ever jump to the right. |
| 7 | + * This means that if we start from the right of the array, every time we |
| 8 | + * will query a position to our right, that position has already be |
| 9 | + * determined as being GOOD or BAD. This means we don't need to recurse |
| 10 | + * anymore, as we will always hit the memo table. |
| 11 | + * |
| 12 | + * We call a position in the array a "good" one if starting at that |
| 13 | + * position, we can reach the last index. Otherwise, that index |
| 14 | + * is called a "bad" one. |
| 15 | + * |
| 16 | + * @param {number[]} numbers - array of possible jump length. |
| 17 | + * @return {boolean} |
| 18 | + */ |
| 19 | +export default function dpBottomUpJumpGame(numbers) { |
| 20 | + // Init cells goodness table. |
| 21 | + const cellsGoodness = Array(numbers.length).fill(undefined); |
| 22 | + // Mark the last cell as "good" one since it is where we ultimately want to get. |
| 23 | + cellsGoodness[cellsGoodness.length - 1] = true; |
| 24 | + |
| 25 | + // Go throw all cells starting from the one before the last |
| 26 | + // one (since the last one is "good" already) and fill cellsGoodness table. |
| 27 | + for (let cellIndex = numbers.length - 2; cellIndex >= 0; cellIndex -= 1) { |
| 28 | + const maxJumpLength = Math.min( |
| 29 | + numbers[cellIndex], |
| 30 | + numbers.length - 1 - cellIndex, |
| 31 | + ); |
| 32 | + |
| 33 | + for (let jumpLength = maxJumpLength; jumpLength > 0; jumpLength -= 1) { |
| 34 | + const nextIndex = cellIndex + jumpLength; |
| 35 | + if (cellsGoodness[nextIndex] === true) { |
| 36 | + cellsGoodness[cellIndex] = true; |
| 37 | + // Once we detected that current cell is good one we don't need to |
| 38 | + // do further cells checking. |
| 39 | + break; |
| 40 | + } |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + // Now, if the zero's cell is good one then we can jump from it to the end of the array. |
| 45 | + return cellsGoodness[0] === true; |
| 46 | +} |
0 commit comments