Given a grid of numbers, find maximum length Snake sequence and print it. If multiple snake sequences exists with the maximum length, print any one of them.
A snake sequence is made up of adjacent numbers in the grid such that for each number, the number on the right or the number below it is +1 or -1 its value. For example, if you are at location (x, y) in the grid, you can either move right i.e. (x, y+1) if that number is ¹ 1 or move down i.e. (x+1, y) if that number is ¹ 1.
For example,
9, 6, 5, 2
8, 7, 6, 5
7, 3, 1, 6
1, 1, 1, 7
In above grid, the longest snake sequence is: (9, 8, 7, 6, 5, 6, 7)
Below figure shows all possible paths –
We strongly recommend you to minimize your browser and try this yourself first.
The idea is to use Dynamic Programming. For each cell of the matrix, we keep maximum length of a snake which ends in current cell. The maximum length snake sequence will have maximum value. The maximum value cell will correspond to tail of the snake. In order to print the snake, we need to backtrack from tail all the way back to snakeâs head.
Let T[i][i] represent maximum length of a snake which ends at cell (i, j), then for given matrix M, the DP relation is defined as –
T[0][0] = 0
T[i][j] = max(T[i][j], T[i][j – 1] + 1) if M[i][j] = M[i][j – 1] Âą 1
T[i][j] = max(T[i][j], T[i – 1][j] + 1) if M[i][j] = M[i – 1][j] Âą 1
Below is the implementation of the idea â
C++
// C++ program to find maximum length // Snake sequence and print it #include <bits/stdc++.h> using namespace std; #define M 4 #define N 4 struct Point { int x, y; }; // Function to find maximum length Snake sequence path // (i, j) corresponds to tail of the snake list<Point> findPath(int grid[M][N], int mat[M][N], int i, int j) { list<Point> path; Point pt = {i, j}; path.push_front(pt); while (grid[i][j] != 0) { if (i > 0 && grid[i][j] - 1 == grid[i - 1][j]) { pt = {i - 1, j}; path.push_front(pt); i--; } else if (j > 0 && grid[i][j] - 1 == grid[i][j - 1]) { pt = {i, j - 1}; path.push_front(pt); j--; } } return path; } // Function to find maximum length Snake sequence void findSnakeSequence(int mat[M][N]) { // table to store results of subproblems int lookup[M][N]; // initialize by 0 memset(lookup, 0, sizeof lookup); // stores maximum length of Snake sequence int max_len = 0; // store cordinates to snake's tail int max_row = 0; int max_col = 0; // fill the table in bottom-up fashion for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { // do except for (0, 0) cell if (i || j) { // look above if (i > 0 && abs(mat[i - 1][j] - mat[i][j]) == 1) { lookup[i][j] = max(lookup[i][j], lookup[i - 1][j] + 1); if (max_len < lookup[i][j]) { max_len = lookup[i][j]; max_row = i, max_col = j; } } // look left if (j > 0 && abs(mat[i][j - 1] - mat[i][j]) == 1) { lookup[i][j] = max(lookup[i][j], lookup[i][j - 1] + 1); if (max_len < lookup[i][j]) { max_len = lookup[i][j]; max_row = i, max_col = j; } } } } } cout << "Maximum length of Snake sequence is: " << max_len << endl; // find maximum length Snake sequence path list<Point> path = findPath(lookup, mat, max_row, max_col); cout << "Snake sequence is:"; for (auto it = path.begin(); it != path.end(); it++) cout << endl << mat[it->x][it->y] << " (" << it->x << ", " << it->y << ")" ; } // Driver code int main() { int mat[M][N] = { {9, 6, 5, 2}, {8, 7, 6, 5}, {7, 3, 1, 6}, {1, 1, 1, 7}, }; findSnakeSequence(mat); return 0; } |
Java
// Java program to find maximum length // Snake sequence and print it import java.util.*; class GFG { static int M = 4; static int N = 4; static class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } }; // Function to find maximum length Snake sequence path // (i, j) corresponds to tail of the snake static List<Point> findPath(int grid[][], int mat[][], int i, int j) { List<Point> path = new LinkedList<>(); Point pt = new Point(i, j); path.add(0, pt); while (grid[i][j] != 0) { if (i > 0 && grid[i][j] - 1 == grid[i - 1][j]) { pt = new Point(i - 1, j); path.add(0, pt); i--; } else if (j > 0 && grid[i][j] - 1 == grid[i][j - 1]) { pt = new Point(i, j - 1); path.add(0, pt); j--; } } return path; } // Function to find maximum length Snake sequence static void findSnakeSequence(int mat[][]) { // table to store results of subproblems int [][]lookup = new int[M][N]; // initialize by 0 // stores maximum length of Snake sequence int max_len = 0; // store cordinates to snake's tail int max_row = 0; int max_col = 0; // fill the table in bottom-up fashion for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { // do except for (0, 0) cell if (i != 0 || j != 0) { // look above if (i > 0 && Math.abs(mat[i - 1][j] - mat[i][j]) == 1) { lookup[i][j] = Math.max(lookup[i][j], lookup[i - 1][j] + 1); if (max_len < lookup[i][j]) { max_len = lookup[i][j]; max_row = i; max_col = j; } } // look left if (j > 0 && Math.abs(mat[i][j - 1] - mat[i][j]) == 1) { lookup[i][j] = Math.max(lookup[i][j], lookup[i][j - 1] + 1); if (max_len < lookup[i][j]) { max_len = lookup[i][j]; max_row = i; max_col = j; } } } } } System.out.print("Maximum length of Snake " + "sequence is: " + max_len + "\n"); // find maximum length Snake sequence path List<Point> path = findPath(lookup, mat, max_row, max_col); System.out.print("Snake sequence is:"); for (Point it : path) System.out.print("\n" + mat[it.x][it.y] + " (" + it.x + ", " + it.y + ")"); } // Driver code public static void main(String[] args) { int mat[][] = {{9, 6, 5, 2}, {8, 7, 6, 5}, {7, 3, 1, 6}, {1, 1, 1, 7}}; findSnakeSequence(mat); } } // This code is contributed by 29AjayKumar |
Python3
# Python program to find maximum length # Snake sequence and print it M = 4N = 4 class Point: def __init__(self, x, y): self.x = x self.y = y # Function to find maximum length Snake sequence path # (i, j) corresponds to tail of the snake def findPath(grid, mat, i, j): path = list() pt = Point(i, j) path.append(pt) while (grid[i][j] != 0): if (i > 0 and grid[i][j]-1 == grid[i-1][j]): pt = Point(i-1, j) path.append(pt) i -= 1 elif (j > 0 and grid[i][j]-1 == grid[i][j-1]): pt = Point(i, j-1) path.append(pt) j -= 1 return path # Function to find maximum length Snake sequence def findSnakeSequence(mat): # table to store results of subproblems # initialize by 0 lookup = [[0 for i in range(N)] for j in range(M)] # stores maximum length of Snake sequence max_len = 0 # store cordinates to snake's tail max_row = 0 max_col = 0 # fill the table in bottom-up fashion for i in range(M): for j in range(N): # do except for (0, 0) cell if (i or j): # look above if (i > 0 and abs(mat[i-1][j] - mat[i][j]) == 1): lookup[i][j] = max(lookup[i][j], lookup[i-1][j] + 1) if (max_len < lookup[i][j]): max_len = lookup[i][j] max_row = i max_col = j # look left if (j > 0 and abs(mat[i][j-1] - mat[i][j]) == 1): lookup[i][j] = max(lookup[i][j], lookup[i][j-1] + 1) if (max_len < lookup[i][j]): max_len = lookup[i][j] max_row = i max_col = j print("Maximum length of Snake sequence is:", max_len) # find maximum length Snake sequence path path = findPath(lookup, mat, max_row, max_col) print("Snake sequence is:") for ele in reversed(path): print(mat[ele.x][ele.y], " (", ele.x, ", ", ele.y, ")", sep = "") # Driver code mat = [[9, 6, 5, 2], [8, 7, 6, 5], [7, 3, 1, 6], [1, 1, 1, 7]] findSnakeSequence(mat) # This code is contributed # by Soumen Ghosh |
C#
// C# program to find maximum length // Snake sequence and print it using System; using System.Collections.Generic; class GFG { static int M = 4; static int N = 4; public class Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } }; // Function to find maximum length Snake sequence path // (i, j) corresponds to tail of the snake static List<Point> findPath(int [,]grid, int [,]mat, int i, int j) { List<Point> path = new List<Point>(); Point pt = new Point(i, j); path.Insert(0, pt); while (grid[i, j] != 0) { if (i > 0 && grid[i, j] - 1 == grid[i - 1, j]) { pt = new Point(i - 1, j); path.Insert(0, pt); i--; } else if (j > 0 && grid[i, j] - 1 == grid[i, j - 1]) { pt = new Point(i, j - 1); path.Insert(0, pt); j--; } } return path; } // Function to find maximum length Snake sequence static void findSnakeSequence(int [,]mat) { // table to store results of subproblems int [,]lookup = new int[M, N]; // initialize by 0 // stores maximum length of Snake sequence int max_len = 0; // store cordinates to snake's tail int max_row = 0; int max_col = 0; // fill the table in bottom-up fashion for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { // do except for (0, 0) cell if (i != 0 || j != 0) { // look above if (i > 0 && Math.Abs(mat[i - 1, j] - mat[i, j]) == 1) { lookup[i, j] = Math.Max(lookup[i, j], lookup[i - 1, j] + 1); if (max_len < lookup[i,j]) { max_len = lookup[i, j]; max_row = i; max_col = j; } } // look left if (j > 0 && Math.Abs(mat[i, j - 1] - mat[i, j]) == 1) { lookup[i, j] = Math.Max(lookup[i, j], lookup[i, j - 1] + 1); if (max_len < lookup[i, j]) { max_len = lookup[i, j]; max_row = i; max_col = j; } } } } } Console.Write("Maximum length of Snake " + "sequence is: " + max_len + "\n"); // find maximum length Snake sequence path List<Point> path = findPath(lookup, mat, max_row, max_col); Console.Write("Snake sequence is:"); foreach (Point it in path) Console.Write("\n" + mat[it.x,it.y] + " (" + it.x + ", " + it.y + ")"); } // Driver code public static void Main(String[] args) { int [,]mat = {{9, 6, 5, 2}, {8, 7, 6, 5}, {7, 3, 1, 6}, {1, 1, 1, 7}}; findSnakeSequence(mat); } } // This code is contributed by Princi Singh |
Output :
Maximum length of Snake sequence is: 6 Snake sequence is: 9 (0, 0) 8 (1, 0) 7 (1, 1) 6 (1, 2) 5 (1, 3) 6 (2, 3) 7 (3, 3)
Time complexity of above solution is O(M*N). Auxiliary space used by above solution is O(M*N). If we are not required to print the snake, space can be further reduced to O(N) as we only uses the result from last row.
Reference: Stack Overflow
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
Recommended Posts:
- Print matrix in snake pattern
- Print matrix in snake pattern from the last column
- Maximum Sequence Length | Collatz Conjecture
- Maximum Length of Sequence of Sums of prime factors generated by the given operations
- Find minimum length sub-array which has given sub-sequence in it
- Minimum sum possible of any bracket sequence of length N
- Total number of odd length palindrome sub-sequence around each centre
- Find maximum sum array of length less than or equal to m
- Find maximum path length in a binary matrix
- Find Maximum side length of square in a Matrix
- Find Maximum Length Of A Square Submatrix Having Sum Of Elements At-Most K
- Maximum sum Bi-tonic Sub-sequence
- Maximum sum possible for a sub-sequence such that no two elements appear at a distance < K in the array
- Maximum sub-sequence sum such that indices of any two adjacent elements differs at least by 3
- Maximum contiguous decreasing sequence obtained by removing any one element
- Number of ways to cut a stick of length N into in even length at most K units long pieces
- Length of longest Palindromic Subsequence of even length with no two adjacent characters same
- Find longest bitonic sequence such that increasing and decreasing parts are from two different arrays
- Maximum Length Chain of Pairs | DP-20
- Print Maximum Length Chain of Pairs


