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
Find maximum length Snake sequence in Python
A snake sequence is a path in a grid where adjacent numbers differ by exactly 1. You can move right or down in the grid, and each step must be to a number that is either +1 or -1 from the current value.
Problem Understanding
Given a grid of numbers, we need to find the longest snake sequence. For example, in this grid ?
| 10 | 7 | 6 | 3 |
| 9 | 8 | 7 | 6 |
| 8 | 4 | 2 | 7 |
| 2 | 2 | 2 | 8 |
The longest snake sequence has length 6: 10 ? 9 ? 8 ? 7 ? 6 ? 7 ? 8
Algorithm
We use dynamic programming to track the maximum sequence length ending at each cell ?
- Create a lookup table to store the maximum sequence length at each position
- For each cell, check if we can extend sequences from the left or top cell
- Keep track of the cell with the maximum sequence length
- Reconstruct the path from that cell
Implementation
def get_path(grid, lookup, i, j):
"""Reconstruct the snake sequence path"""
path = []
pt = [i, j]
path.append(pt)
while lookup[i][j] != 0:
if (i > 0 and lookup[i][j] - 1 == lookup[i-1][j]):
pt = [i-1, j]
path.append(pt)
i -= 1
elif (j > 0 and lookup[i][j] - 1 == lookup[i][j-1]):
pt = [i, j-1]
path.append(pt)
j -= 1
else:
break
return path
def find_max_snake_sequence(grid):
M = len(grid)
N = len(grid[0])
# Create lookup table for dynamic programming
lookup = [[0 for _ in range(N)] for _ in range(M)]
length_max = 0
max_row = 0
max_col = 0
# Fill the lookup table
for i in range(M):
for j in range(N):
if i == 0 and j == 0:
lookup[i][j] = 0
else:
# Check cell above
if (i > 0 and abs(grid[i-1][j] - grid[i][j]) == 1):
lookup[i][j] = max(lookup[i][j], lookup[i-1][j] + 1)
# Check cell to the left
if (j > 0 and abs(grid[i][j-1] - grid[i][j]) == 1):
lookup[i][j] = max(lookup[i][j], lookup[i][j-1] + 1)
# Update maximum length found
if length_max < lookup[i][j]:
length_max = lookup[i][j]
max_row = i
max_col = j
# Get the actual sequence
path = get_path(grid, lookup, max_row, max_col)
return length_max + 1, path # +1 because we count the starting cell
# Example usage
grid = [
[10, 7, 6, 3],
[9, 8, 7, 6],
[8, 4, 2, 7],
[2, 2, 2, 8]
]
max_length, sequence_path = find_max_snake_sequence(grid)
print("Maximum length:", max_length)
print("Sequence is:")
for cell in reversed(sequence_path):
i, j = cell[0], cell[1]
print(f"{grid[i][j]} [{i}, {j}]")
Maximum length: 7 Sequence is: 10 [0, 0] 9 [1, 0] 8 [1, 1] 7 [1, 2] 6 [1, 3] 7 [2, 3] 8 [3, 3]
How It Works
The algorithm uses dynamic programming where lookup[i][j] stores the maximum snake sequence length ending at position (i, j). For each cell, we check if we can extend sequences from adjacent cells (top or left) where the value differs by exactly 1.
Time Complexity
- Time Complexity: O(M × N) where M and N are the grid dimensions
- Space Complexity: O(M × N) for the lookup table
Conclusion
This dynamic programming solution efficiently finds the maximum length snake sequence by building up solutions from smaller subproblems. The key insight is tracking the longest sequence ending at each cell and reconstructing the optimal path.
