Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to check we can spell out the target by a list of words or not in Python
Given a list of numbers and a starting index, we need to determine if we can reach the end of the list by jumping. At any index i, we can move left or right by exactly nums[i] steps.
For example, with nums = [0, 0, 2, 1, 3, 3, 1, 1] and starting index k = 2, we can reach the end by jumping from index 2 to index 4, then to the last index 7.
Algorithm
We'll use a breadth-first search (BFS) approach to explore all possible positions:
- Initialize a visited array to track explored positions
- Use a stack to store positions to visit
- For each position, calculate left and right jumps
- Return True if we reach the last index
Implementation
def can_reach_end(nums, k):
n = len(nums)
visited = [False] * n
to_visit = [k]
while to_visit:
i = to_visit.pop()
# Check if we reached the end
if i == n - 1:
return True
# Skip if already visited
if visited[i]:
continue
# Mark as visited
visited[i] = True
# Calculate possible jumps
right_jump = i + nums[i]
left_jump = i - nums[i]
# Add valid positions to visit
if right_jump < n:
to_visit.append(right_jump)
if left_jump >= 0:
to_visit.append(left_jump)
return False
# Test the function
nums = [0, 0, 2, 1, 3, 3, 1, 1]
k = 2
result = can_reach_end(nums, k)
print(f"Can reach end: {result}")
Can reach end: True
Step-by-Step Trace
Let's trace through the example to understand how it works:
def can_reach_end_with_trace(nums, k):
n = len(nums)
visited = [False] * n
to_visit = [k]
print(f"Starting at index {k}")
while to_visit:
i = to_visit.pop()
print(f"Current position: {i}, value: {nums[i]}")
if i == n - 1:
print(f"Reached the end at index {i}!")
return True
if visited[i]:
print(f"Already visited {i}, skipping")
continue
visited[i] = True
right_jump = i + nums[i]
left_jump = i - nums[i]
print(f" Can jump to: left={left_jump}, right={right_jump}")
if right_jump < n:
to_visit.append(right_jump)
if left_jump >= 0:
to_visit.append(left_jump)
print("Cannot reach the end")
return False
# Trace the example
nums = [0, 0, 2, 1, 3, 3, 1, 1]
k = 2
result = can_reach_end_with_trace(nums, k)
Starting at index 2 Current position: 2, value: 2 Can jump to: left=0, right=4 Current position: 0, value: 0 Can jump to: left=0, right=0 Current position: 4, value: 3 Can jump to: left=1, right=7 Current position: 7, value: 1 Reached the end at index 7!
Alternative Approaches
Here's a comparison of different approaches:
| Approach | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| BFS (Stack) | O(n) | O(n) | General case |
| BFS (Queue) | O(n) | O(n) | Shortest path |
| DFS (Recursion) | O(n) | O(n) | Simple implementation |
Edge Cases
Let's test some edge cases:
# Test edge cases
test_cases = [
([1], 0), # Single element
([0, 1, 0], 0), # Can't move from start
([2, 0, 1], 0), # Jump over middle
([1, 1, 1, 1], 1) # Sequential jumps
]
for i, (nums, k) in enumerate(test_cases):
result = can_reach_end(nums, k)
print(f"Test {i+1}: nums={nums}, k={k} ? {result}")
Test 1: nums=[1], k=0 ? True Test 2: nums=[0, 1, 0], k=0 ? False Test 3: nums=[2, 0, 1], k=0 ? True Test 4: nums=[1, 1, 1, 1], k=1 ? True
Conclusion
This solution uses BFS to explore all reachable positions from the starting index. The algorithm efficiently tracks visited positions to avoid cycles and returns True when the last index is reached.
