diff --git a/src/my_project/interviews/top_150_questions_round_23/ex_09_jump_game_i.py b/src/my_project/interviews/top_150_questions_round_23/ex_09_jump_game_i.py new file mode 100644 index 00000000..738b5b66 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_23/ex_09_jump_game_i.py @@ -0,0 +1,49 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class Solution: + + def canJump(self, nums: List[int]) -> bool: + """ + Determine if we can jump from index 0 to the last index. + + Strategy: Greedy backward traversal + - Work backwards from the end + - Track the leftmost position that can reach the goal + - If we can reach index 0, return True + + Time: O(n), Space: O(n) - can be optimized to O(1) + """ + + n = len(nums) + + # Base case: already at the end + if n == 1: + return True + + # dp[i] = 1 means position i can reach the end + dp = [0] * n + + # Start from the last index (our goal) + prev_best = n - 1 + step = n - 1 + + # Iterate backwards from second-to-last to first index + for i in range(n - 2, -1, -1): + # Maximum jump length from current position + step = nums[i] + + # Check if current position can reach any "good" position + # (i + step) is the farthest we can jump from position i + if (i + step) >= prev_best: + # Mark this position as reachable to the end + dp[i] = 1 + + # Update the leftmost position that can reach the end + prev_best = i + + # Check if we can reach the end from the start (index 0) + if dp[0]: + return True + + return False \ No newline at end of file diff --git a/src/my_project/interviews_typescript/top_150_questions_round_23/ex_09_jump_game_i.ts b/src/my_project/interviews_typescript/top_150_questions_round_23/ex_09_jump_game_i.ts new file mode 100644 index 00000000..3da19c1c --- /dev/null +++ b/src/my_project/interviews_typescript/top_150_questions_round_23/ex_09_jump_game_i.ts @@ -0,0 +1,31 @@ +function canJump(nums: number[]): boolean { + const n = nums.length; + + // Base case: already at the end + if (n === 1) return true; + + // dp[i] = 1 means position i can reach the end + const dp: number[] = new Array(n).fill(0); + + // Start from the last index (our goal) + let prevBest = n - 1; + + // Iterate backwards from second-to-last to first index + for (let i = n - 2; i >= 0; i--) { + // Maximum jump length from current position + const step = nums[i]; + + // Check if current position can reach any "good" position + if (i + step >= prevBest) { + // Mark this position as reachable to the end + dp[i] = 1; + + // Update the leftmost position that can reach the end + prevBest = i; + } + } + + // Check if we can reach the end from the start (index 0) + return dp[0] === 1; +} + diff --git a/tests/test_150_questions_round_23/test_09_jump_game_i_round_23.py b/tests/test_150_questions_round_23/test_09_jump_game_i_round_23.py new file mode 100644 index 00000000..5aaa12a7 --- /dev/null +++ b/tests/test_150_questions_round_23/test_09_jump_game_i_round_23.py @@ -0,0 +1,15 @@ +import unittest +from src.my_project.interviews.top_150_questions_round_23\ +.ex_09_jump_game_i import Solution + +class JumpITestCase(unittest.TestCase): + + def test_jump_i_first_case_true(self): + solution = Solution() + output = solution.canJump(nums = [2,3,1,1,4]) + self.assertTrue(output) + + def test_jump_i_first_case_false(self): + solution = Solution() + output = solution.canJump(nums = [3,2,1,0,4]) + self.assertFalse(output) \ No newline at end of file