Snake in Matrix solution and explanation
9 more videos on this problem
LeetCode 3248 | easy | Snake in Matrix | Python code explanationTechtonic Knights · 2:08 · 728 views
Leetcode | 3248. Snake in Matrix | Easy | Java SolutionDeveloper Docs · 5:35 · 665 views
leetcode 3248 : snake in matrix : python solutionleetcode blind 75 · 3:50 · 363 views
3248. Snake in Matrix (Leetcode Easy)Programming Live with Larry · 5:27 · 357 views
Snake in Matrix | Matrix | LeetCode 3248 + Full ExplanationCodeInBits · 4:44 · 297 views
3248 Snake in Matrix || How to 🤔 in Interview || Simple Logic 🔥Ayush Rao · 4:14 · 261 views
3248. Snake in Matrix #leetcode #2darray #javaprogramming #dsa #dsalgo #coding #arraylist #arraysCodeVia · 2:46 · 83 views
Leetcode || Problem: 3248 || Snake in Matrix || Easy Solution with arrays and hashmapsSripriya Agarwal · 34:23 · 67 views
Snake in Matrix LeetCode - 3248BugToBuild · 2:52 · 61 views
Leetcode 3248 Snake in MatrixAlgorithmicIQ · 12:18 · 34 views
The problem
There is a snake in an n x n matrix grid and can move in four possible directions. Each cell in the grid is identified by the position: grid[i][j] = (i * n) + j.
The snake starts at cell 0 and follows a sequence of commands.
You are given an integer n representing the size of the grid and an array of strings commands where each command[i] is either "UP", "RIGHT", "DOWN", and "LEFT". It's guaranteed that the snake will remain within the grid boundaries throughout its movement.
Return the position of the final cell where the snake ends up after executing commands.
Example 1:
Input: n = 2, commands = ["RIGHT","DOWN"]
Output: 3
Explanation:
| 0 | 1 |
| 2 | 3 |
| 0 | 1 |
| 2 | 3 |
| 0 | 1 |
| 2 | 3 |
Example 2:
Input: n = 3, commands = ["DOWN","RIGHT","UP"]
Output: 1
Explanation:
| 0 | 1 | 2 |
| 3 | 4 | 5 |
| 6 | 7 | 8 |
| 0 | 1 | 2 |
| 3 | 4 | 5 |
| 6 | 7 | 8 |
| 0 | 1 | 2 |
| 3 | 4 | 5 |
| 6 | 7 | 8 |
| 0 | 1 | 2 |
| 3 | 4 | 5 |
| 6 | 7 | 8 |
Constraints:
2 <= n <= 101 <= commands.length <= 100commandsconsists only of"UP","RIGHT","DOWN", and"LEFT".- The input is generated such the snake will not move outside of the boundaries.
Approach overview
Problem Overview: You start with a snake at the top-left corner of an n x n matrix (cell index 0). A list of movement commands such as UP, DOWN, LEFT, and RIGHT is given. After applying each move, return the final cell number assuming the matrix is indexed in row-major order.
Approach 1: Coordinate Mapping Approach (O(k) time, O(1) space)
Track the snake’s position using two integers: row and col. Initialize both to 0. Iterate through the command list and update coordinates based on the direction: decrement row for UP, increment row for DOWN, decrement col for LEFT, and increment col for RIGHT. After processing all moves, convert the 2D position into the matrix’s linear index using row * n + col. The key insight is that the matrix numbering follows row-major order, so a simple arithmetic mapping gives the final answer without storing the grid.
This method is a straightforward simulation. Each command results in a constant-time coordinate update. No extra data structures are required, making the space complexity O(1). This approach is easy to implement and works efficiently even for large command lists.
Approach 2: Direction Vector Approach (O(k) time, O(1) space)
Instead of multiple condition checks, store movement offsets in a direction map. For example, map each command to a vector: UP (-1,0), DOWN (1,0), LEFT (0,-1), and RIGHT (0,1). Iterate through the commands and update the current position using these vectors. This reduces branching logic and keeps the movement rules centralized.
The vector-based solution is common in grid traversal problems involving arrays and directional movement. Each iteration performs a constant-time vector addition to update the coordinates, keeping time complexity at O(k) where k is the number of commands. Space remains O(1) since only a few variables and a small direction map are used.
Recommended for interviews: The Coordinate Mapping approach is usually what interviewers expect first. It shows you understand how row-major indexing works and can simulate movement in a grid efficiently. The Direction Vector approach is slightly cleaner and scales better when more directions or movement rules are added. Demonstrating both shows strong understanding of string-driven simulations and grid traversal patterns.
Approach 1: Coordinate Mapping Approach
This approach leverages the understanding that each movement updates either the row or column of the snake's position. We keep track of the current position as coordinates (x, y) and apply transformations based on each command. Finally, convert the coordinates back to the one-dimensional index.
def final_position(n, commands):
x, y = 0, 0
for command in commands:
if command == 'UP':
x -= 1
elif command == 'DOWN':
x += 1
elif command == 'LEFT':
y -= 1
elif command == 'RIGHT':
y += 1
return x * n + y
# Example usage
commands = ['RIGHT', 'DOWN']
print(final_position(2, commands)) # Output: 3import java.util.*;
public class SnakeGame {
public static int finalPosition(int n, List<String> commands) {
int x = 0, y = 0;
for (String command : commands) {
switch (command) {
case "UP":
x--;
break;
case "DOWN":
x++;
break;
case "LEFT":
y--;
break;
case "RIGHT":
y++;
break;
}
}
return x * n + y;
}
public static void main(String[] args) {
List<String> commands = Arrays.asList("RIGHT", "DOWN");
System.out.println(finalPosition(2, commands)); // Output: 3
}
}#include <iostream>
#include <vector>
#include <string>
int finalPosition(int n, const std::vector<std::string>& commands) {
int x = 0, y = 0;
for (const auto& command : commands) {
if (command == "UP") --x;
else if (command == "DOWN") ++x;
else if (command == "LEFT") --y;
else if (command == "RIGHT") ++y;
}
return x * n + y;
}
int main() {
std::vector<std::string> commands = {"RIGHT", "DOWN"};
std::cout << finalPosition(2, commands) << std::endl; // Output: 3
return 0;
}function finalPosition(n, commands) {
let x = 0, y = 0;
commands.forEach(command => {
switch (command) {
case 'UP':
x -= 1;
break;
case 'DOWN':
x += 1;
break;
case 'LEFT':
y -= 1;
break;
case 'RIGHT':
y += 1;
break;
}
});
return x * n + y;
}
// Example
const commands = ['RIGHT', 'DOWN'];
console.log(finalPosition(2, commands)); // Output: 3#include <stdio.h>
#include <string.h>
int finalPosition(int n, char commands[][7], int commandCount) {
int x = 0, y = 0;
for (int i = 0; i < commandCount; i++) {
if (strcmp(commands[i], "UP") == 0) {
x--;
} else if (strcmp(commands[i], "DOWN") == 0) {
x++;
} else if (strcmp(commands[i], "LEFT") == 0) {
y--;
} else if (strcmp(commands[i], "RIGHT") == 0) {
y++;
}
}
return x * n + y;
}
int main() {
char commands[2][7] = {"RIGHT", "DOWN"}; // Sample input
int result = finalPosition(2, commands, 2);
printf("%d\n", result); // Expected output: 3
return 0;
}using System;
using System.Collections.Generic;
public class SnakeMatrix {
public static int FinalPosition(int n, List<string> commands) {
int x = 0, y = 0;
foreach (var command in commands) {
switch (command) {
case "UP":
x--;
break;
case "DOWN":
x++;
break;
case "LEFT":
y--;
break;
case "RIGHT":
y++;
break;
}
}
return x * n + y;
}
public static void Main() {
var commands = new List<string> {"RIGHT", "DOWN"};
Console.WriteLine(FinalPosition(2, commands)); // Output: 3
}
}This Python implementation initializes coordinates (x, y) at (0, 0). It modifies them according to each command and computes the resulting position using x * n + y.
Time Complexity: O(m), where m is the number of commands.
Space Complexity: O(1), maintaining only positional variables.
Approach 2: Vector Approach
This approach represents movement directional changes as vectors (changes in the coordinate positions). The commands map to these vectors which modify the position cumulatively. This approach simplifies direction handling and makes calculations straightforward.
def final_position(n, commands):
x, y = 0, 0
direction_map = {
'UP': (-1, 0),
'DOWN': (1, 0),
'LEFT': (0, -1),
'RIGHT': (0, 1)
}
for command in commands:
dx, dy = direction_map[command]
x += dx
y += dy
return x * n + y
# Example usage
commands = ['DOWN', 'RIGHT', 'UP']
print(final_position(3, commands)) # Output: 1import java.util.*;
public class SnakeGame {
public static int finalPosition(int n, List<String> commands) {
int x = 0, y = 0, dx, dy;
for (String command : commands) {
if (command.equals("UP")) { dx = -1; dy = 0; }
else if (command.equals("DOWN")) { dx = 1; dy = 0; }
else if (command.equals("LEFT")) { dx = 0; dy = -1; }
else { dx = 0; dy = 1; }
x += dx;
y += dy;
}
return x * n + y;
}
public static void main(String[] args) {
List<String> commands = Arrays.asList("DOWN", "RIGHT", "UP");
System.out.println(finalPosition(3, commands)); // Output: 1
}
}#include <iostream>
#include <vector>
#include <string>
int finalPosition(int n, const std::vector<std::string>& commands) {
int x = 0, y = 0;
for (const auto& command : commands) {
if (command == "UP") { x += -1; y += 0; }
else if (command == "DOWN") { x += 1; y += 0; }
else if (command == "LEFT") { x += 0; y += -1; }
else if (command == "RIGHT") { x += 0; y += 1; }
}
return x * n + y;
}
int main() {
std::vector<std::string> commands = {"DOWN", "RIGHT", "UP"};
std::cout << finalPosition(3, commands) << std::endl; // Output: 1
return 0;
}function finalPosition(n, commands) {
let x = 0, y = 0;
const directionMap = {
'UP': [-1, 0],
'DOWN': [1, 0],
'LEFT': [0, -1],
'RIGHT': [0, 1]
};
commands.forEach(command => {
const [dx, dy] = directionMap[command];
x += dx;
y += dy;
});
return x * n + y;
}
// Example
const commands = ['DOWN', 'RIGHT', 'UP'];
console.log(finalPosition(3, commands)); // Output: 1#include <stdio.h>
#include <string.h>
int finalPosition(int n, char commands[][7], int commandCount) {
int x = 0, y = 0;
int dx, dy;
for (int i = 0; i < commandCount; i++) {
if (strcmp(commands[i], "UP") == 0) { dx = -1; dy = 0; }
else if (strcmp(commands[i], "DOWN") == 0) { dx = 1; dy = 0; }
else if (strcmp(commands[i], "LEFT") == 0) { dx = 0; dy = -1; }
else if (strcmp(commands[i], "RIGHT") == 0) { dx = 0; dy = 1; }
x += dx;
y += dy;
}
return x * n + y;
}
int main() {
char commands[3][7] = {"DOWN", "RIGHT", "UP"};
int result = finalPosition(3, commands, 3);
printf("%d\n", result); // Expected output: 1
return 0;
}using System;
using System.Collections.Generic;
public class SnakeMatrix {
public static int FinalPosition(int n, List<string> commands) {
int x = 0, y = 0, dx, dy;
foreach (var command in commands) {
if (command == "UP") { dx = -1; dy = 0; }
else if (command == "DOWN") { dx = 1; dy = 0; }
else if (command == "LEFT") { dx = 0; dy = -1; }
else { dx = 0; dy = 1; }
x += dx;
y += dy;
}
return x * n + y;
}
public static void Main() {
var commands = new List<string> {"DOWN", "RIGHT", "UP"};
Console.WriteLine(FinalPosition(3, commands)); // Output: 1
}
}In Python, a dictionary direction_map is used to simplify coordinate updates. This dictionary maps each command to a directional vector, allowing concise positional calculations.
Time Complexity: O(m), with m commands processed.
Space Complexity: O(1), maintaining constant extra space.
Approach 3: Simulation
We can use two variables x and y to represent the position of the snake. Initially, x = y = 0. Then, we traverse commands and update the values of x and y based on the current command. Finally, we return x times n + y.
The time complexity is O(n), where n is the length of the array commands. The space complexity is O(1).
function finalPositionOfSnake(n: number, commands: string[]): number {
let [x, y] = [0, 0];
for (const c of commands) {
c[0] === 'U' && x--;
c[0] === 'D' && x++;
c[0] === 'L' && y--;
c[0] === 'R' && y++;
}
return x * n + y;
}func finalPositionOfSnake(n int, commands []string) int {
x, y := 0, 0
for _, c := range commands {
switch c[0] {
case 'U':
x--
case 'D':
x++
case 'L':
y--
case 'R':
y++
}
}
return x*n + y
}Complexity comparison
| Approach | Complexity |
|---|---|
| Coordinate Mapping Approach | Time Complexity: |
| Vector Approach | Time Complexity: |
| Simulation | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Coordinate Mapping Approach | O(k) | O(1) | Best for simple grid simulations where row and column tracking is enough |
| Direction Vector Approach | O(k) | O(1) | Cleaner implementation when working with multiple directions or reusable grid movement logic |
Frequently asked questions
Is Snake in Matrix easy or hard?
Snake in Matrix is categorized as an Easy problem. It mainly tests basic grid simulation, coordinate updates, and understanding of row-major indexing. The optimal solution is straightforward and runs in linear time with constant space.
Snake in Matrix Python/Java solution
The implementation is identical across languages. Maintain row and column variables, iterate through the command list, update coordinates for each direction, and compute the final index using row * n + col. This approach works in Python, Java, C++, JavaScript, and C#.
How to solve Snake in Matrix in O(k)?
Initialize row = 0 and col = 0 to represent the starting cell. Iterate through the command list and update the coordinates based on the direction. After processing all moves, compute the final index using row * n + col. This single pass over the commands gives an O(k) time solution.
What is the best approach for Snake in Matrix?
The coordinate mapping simulation is the most common solution. Track the snake’s row and column while processing each direction command, then convert the final position to a linear index using row * n + col. This runs in O(k) time with O(1) space where k is the number of moves.
Is Snake in Matrix asked at Google/Amazon/Meta?
Snake in Matrix is primarily a LeetCode-style simulation problem rather than a frequently reported FAANG interview question. However, similar grid simulation and coordinate tracking problems appear in interviews at companies like Amazon and Google.
What data structure is used in Snake in Matrix?
The solution mainly uses primitive variables to track row and column coordinates. Some implementations also use a small direction map or vector table to convert commands into movement offsets. No complex data structures are required.
What is the time complexity of Snake in Matrix?
The time complexity is O(k), where k is the number of movement commands. Each command results in a constant-time coordinate update. Space complexity remains O(1) since only the current row and column are stored.
