Find maximum length Snake sequence
Last Updated :
17 Nov, 2022
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 coordinates 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 coordinates 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
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 coordinates 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
Python3
def snakesequence(S, m, n):
sequence = {}
DP = [[1 for x in range(m+1)] for x in range(n+1)]
a, b, maximum = 0, 0, 0
position = [0, 0]
for i in range(0, n+1):
for j in range(0, m+1):
a, b = 0, 0
p = "initial"
if(i > 0 and abs(S[i][j] - S[i-1][j]) == 1):
a = DP[i-1][j]
if(j > 0 and abs(S[i][j] - S[i][j-1]) == 1):
b = DP[i][j-1]
if a != 0 and a >= b:
p = str(i-1) + " " + str(j)
elif b != 0:
p = str(i) + " " + str(j-1)
q = str(i) + " " + str(j)
sequence[q] = p
DP[i][j] = DP[i][j] + max(a, b)
if DP[i][j] >= maximum:
maximum = DP[i][j]
position[0] = i
position[1] = j
snakeValues = []
snakePositions = []
snakeValues.append(S[position[0]][position[1]])
check = 'found'
str_next = str(position[0]) + " " + str(position[1])
findingIndices = sequence[str_next].split()
while(check == 'found'):
if sequence[str_next] == 'initial':
snakePositions.insert(0, str_next)
check = 'end'
continue
findingIndices = sequence[str_next].split()
g = int(findingIndices[0])
h = int(findingIndices[1])
snakeValues.insert(0, S[g][h])
snake_position = str(g) + " " + str(h)
snakePositions.insert(0, str_next)
str_next = sequence[str_next]
return [snakeValues, snakePositions]
S = [[9, 6, 5, 2],
[8, 7, 6, 5],
[7, 3, 1, 6],
[1, 1, 10, 7]]
m = 3
n = 3
seq = snakesequence(S, m, n)
for i in range(len(seq[0])):
print(seq[0][i], ",", seq[1][i].split())
JavaScript
function snakesequence(S, m, n)
{
let sequence = {}
let DP = new Array(n + 1)
for (var i = 0; i <= n; i++)
DP[i] = new Array(m + 1).fill(1)
let a = 0, b = 0, maximum = 0
let position = [0, 0]
for (var i = 0; i <= n; i++)
{
for (var j = 0; j <= m; j++)
{
a = 0
b = 0
let p = "initial"
if(i > 0 && Math.abs(S[i][j] - S[i-1][j]) == 1)
a = DP[i-1][j]
if(j > 0 && Math.abs(S[i][j] - S[i][j-1]) == 1)
b = DP[i][j-1]
if (a != 0 && a >= b)
p = String(i-1) + " " + String(j)
else if (b != 0)
p = String(i) + " " + String(j-1)
let q = String(i) + " " + String(j)
sequence[q] = p
DP[i][j] = DP[i][j] + Math.max(a, b)
if (DP[i][j] >= maximum)
{
maximum = DP[i][j]
position[0] = i
position[1] = j
}
}
}
let snakeValues = []
let snakePositions = []
snakeValues.push(S[position[0]][position[1]])
let check = 'found'
let String_next = String(position[0]) + " " + String(position[1])
let findingIndices = sequence[String_next].split(" ")
while(check == 'found')
{
if (sequence[String_next] == 'initial')
{
snakePositions.unshift(String_next)
check = 'end'
continue
}
findingIndices = sequence[String_next].split(" ")
let g = parseInt(findingIndices[0])
let h = parseInt(findingIndices[1])
snakeValues.unshift(S[g][h])
let snake_position = String(g) + " " + String(h)
snakePositions.unshift(String_next)
String_next = sequence[String_next]
}
return [snakeValues, snakePositions]
}
// Driver Code
let S = [[9, 6, 5, 2],
[8, 7, 6, 5],
[7, 3, 1, 6],
[1, 1, 10, 7]]
let m = 3
let n = 3
let seq = snakesequence(S, m, n)
for (var i = 0; i < seq[0].length; i++)
console.log(seq[0][i] + ",", seq[1][i].split(" "))
OutputMaximum 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.
Similar Reads
Print Maximum Length Chain of Pairs
You are given n pairs of numbers. In every pair, the first number is always smaller than the second number. A pair (c, d) can follow another pair (a, b) if b < c. Chain of pairs can be formed in this fashion. Find the longest chain which can be formed from a given set of pairs. Examples: Input: (
8 min read
Longest mutation sequence
Given a list of conversion tuples Arr[], such that string Arr[i][0] gets converted to string Arr[i][1]. A character is considered good if it has one-to-one mapping to some other character throughout all the conversions, for example during conversion of "abb" to "abc", b->c is considered good. You
9 min read
Sequence and Series in Python
Sequences and series are fundamental concepts in mathematics. A Sequence is an ordered list of numbers following a specific pattern, while a series is the sum of the elements of a sequence. This tutorial will cover arithmetic sequences, geometric sequences, and how to work with them in Python. Arith
5 min read
Longest Prefix Subsequence matching Fibonacci Sequence
Given an array arr of size N. Also, there is another array B of the infinite size where B[0] = B[1] = 1, and for all (i >= 2), B[i] = B[i-1]+B[i-2], the task is to find the length of the longest subsequence which is the prefix of array B. If there is no subsequence which is the prefix of array B
5 min read
Longest Common Subsequence | DP using Memoization
Given two strings s1 and s2, the task is to find the length of the longest common subsequence present in both of them. Examples: Input: s1 = âABCDGHâ, s2 = âAEDFHRâ Output: 3 LCS for input Sequences âAGGTABâ and âGXTXAYBâ is âGTABâ of length 4. Input: s1 = âstriverâ, s2 = ârajâ Output: 1 The naive s
13 min read
Baum Sweet Sequence
Baum Sweet Sequence is an infinite binary sequence of 0s and 1s. The nth term of the sequence is 1 if the number n has no odd number of contiguous zeroes in its binary representation, else the nth term is 0. The first few terms of the sequence are: b1 = 1 (binary of 1 is 1) b2 = 0 (binary of 2 is 10
5 min read
Longest Bitonic Subsequence
Given an array arr[] containing n positive integers, a subsequence of numbers is called bitonic if it is first strictly increasing, then strictly decreasing. The task is to find the length of the longest bitonic subsequence. Note: Only strictly increasing (no decreasing part) or a strictly decreasin
15+ min read
Look-and-Say Sequence
Find the nth term in Look-and-say (Or Count and Say) Sequence. The look-and-say sequence is the sequence of the below integers: 1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ... How is the above sequence generated? The nth term is generated by reading (n-1)th term.The first term is "1"Secon
10 min read
Mathematical Algorithms - Sequence & Series
Mathematical algorithms are step-by-step procedures used to solve math problems. This article looks at sequences and series, which are important parts of these algorithms. Sequences are ordered sets of numbers, while series are the sums of these numbers. Understanding sequences and series is vital f
4 min read
Golomb Sequence | Set 2
Given a number N. The task is to find the first N terms of the Golomb Sequence. Golomb sequence is a non-decreasing integer sequence where the n-th term is equal to the number of times n appears in the sequence. Input: N = 11 Output: 1 2 2 3 3 4 4 4 5 5 5 Explanation: The first term is 1. 1 appears
8 min read