C++ 0059.cpp
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
if (n == 1)
return { { 1 }};
// see problem 54
vector<vector<int>> result;
result.resize(n);
for (auto& r : result)
r.resize(n, 0);
int dx = 1;
int dy = 0;
int x = 0;
int y = 0;
int value = 1;
while (true)
{
if (result[y][x] > 0)
break;
result[y][x] = value++;
x += dx;
y += dy;
if (x < 0 || y < 0 || y >= n || x >= n || result[y][x] > 0)
{
x -= dx;
y -= dy;
if (dx == +1) { dx = 0; dy = +1; }
else if (dx == -1) { dx = 0; dy = -1; }
else if (dy == +1) { dx = -1; dy = 0; }
else { dx = +1; dy = 0; }
x += dx;
y += dy;
}
}
return result;
}
};
Difficulty
and has an acceptance rate of about 76% (1+ million submissions).
Typical patterns to solve this problem:
- Array
- Matrix
- Simulation
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation generates an n x n matrix filled with the integers from 1 to n² in a clockwise spiral order. It follows a procedural approach: allocate the matrix, walk through the cells while maintaining a direction vector, and turn whenever the next step would leave the bounds or encounter an already-filled cell. The algorithm terminates when the next cell to write is already occupied, which indicates that the entire matrix has been populated.
Matrix Allocation
The code begins by handling the trivial case where n equals 1, returning a single-element matrix immediately. For larger sizes it creates a two-dimensional vector and explicitly resizes each row to contain n zeros. This pre-allocation guarantees that every cell is addressable without further dynamic growth.
vector<vector<int>> result;
result.resize(n);
for (auto& r : result)
r.resize(n, 0);
Direction Management
Movement across the matrix is driven by two integer variables, dx and dy, which together represent the current step direction. The initial direction is set to move right (dx = 1, dy = 0). After each placement the coordinates are updated by adding the direction components.
int dx = 1;
int dy = 0;
int x = 0;
int y = 0;
When the next position would be invalid-either out of bounds or already occupied-the algorithm reverses the last move, rotates the direction clockwise, and then proceeds one step in the new direction. The rotation logic is expressed as a series of conditional assignments that map each cardinal direction to the next one in the clockwise sequence.
if (x < 0 || y < 0 || y >= n || x >= n || result[y][x] > 0)
{
x -= dx;
y -= dy;
if (dx == +1) { dx = 0; dy = +1; }
else if (dx == -1) { dx = 0; dy = -1; }
else if (dy == +1) { dx = -1; dy = 0; }
else { dx = +1; dy = 0; }
x += dx;
y += dy;
}
Value Insertion Loop
The core of the algorithm is a while (true) loop that continues until a termination condition is met. Inside the loop the current cell is checked; if it already contains a positive value, the loop breaks, signalling completion. Otherwise the current value is written, the counter is incremented, and the coordinates are advanced according to the current direction.
int value = 1;
while (true)
{
if (result[y][x] > 0)
break;
result[y][x] = value++;
x += dx;
y += dy;
// boundary and collision handling follows
}
Edge Cases Handled
The implementation explicitly addresses the smallest possible matrix size (n == 1) by returning a pre-filled 1×1 matrix, avoiding any further processing. During traversal, the condition that checks for out-of-range indices (x < 0 || y < 0 || y >= n || x >= n) prevents illegal memory access. The additional test result[y][x] > 0 ensures that the algorithm does not overwrite cells that have already been assigned, which also serves as the termination trigger when the spiral has closed on itself.
Performance Optimizations
The code minimizes overhead by allocating the full matrix up front, eliminating the need for repeated resizing or push-back operations during the fill phase. Direction changes are performed with simple integer assignments rather than more costly data structures such as lookup tables or enumerations. The loop body contains only a handful of arithmetic and conditional checks, keeping the per-iteration cost low. By using a single contiguous vector<vector<int>> layout, cache locality is improved when accessing rows sequentially during the fill process.
Overall, the solution delivers a clear, deterministic traversal that fills the matrix in linear time relative to the number of cells, while keeping memory usage predictable through upfront allocation.
ELI5 - Simplified Explanation
Imagine a shiny empty box made of smaller square tiles. The goal is to fill every single tile with a number, starting from one and counting up as high as possible. To do this, a path is drawn that travels in a spiral, just like a snake winding its way inward toward the middle of the box.
The computer starts at the top left corner and begins walking along the edge. It keeps track of its direction, moving sideways or up and down to follow the spiral shape. Every time the computer steps into a new square, it leaves behind a number. It keeps going until it hits a wall or a space that is already filled with a number. When that happens, the computer stops, turns a corner to change its direction, and keeps moving forward again. It repeats this turn and step pattern over and over until every single square is full and the whole path is complete.
Code Quality
Complexity Analysis
As a rule of thumb, the maximum input size for one second execution time is
- factorial: up to 10 elements
- exponential: up to 20 elements
- polynomial: a few thousand elements
- loglinear: up to 100,000 elements
- linear: a few million elements
- logarithmic: a billion elements
- constant: practically unlimited
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | ||||||||||
| www | AlgoMonster | C++ | Python | Java | TS | ||||||
| WalkCCC | C++ | Python | Java | ||||||||
| leetcode.ca | C++ | Python | Java | Rust | JS | Go | TS | ||||
| LeetcodeHelp | C++ | Python | Java | ||||||||
| MemoryLimitExceeded | C++ | Python | |||||||||
| Progiez | C++ | Python | Java | ||||||||
| github | aylei | Rust | |||||||||
| begeekmyfriend | C | ||||||||||
| BigEggStudy | C# | ||||||||||
| black-shadows | C++ | ||||||||||
| chandansgowda | Python | ||||||||||
| charles-wangkai | Java | ||||||||||
| chenyanzhe | C++ | ||||||||||
| everthis | JS | ||||||||||
| fartem | Ruby | ||||||||||
| fengvyi | C++ | ||||||||||
| fpdjsns | C++ | ||||||||||
| gaosq0604 | Python | ||||||||||
| halfrost | Go | ||||||||||
| JoshCrozier | JS | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| lennylxx | C | ||||||||||
| linouk23 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| luangong | C++ | ||||||||||
| MacJim | C++ | ||||||||||
| qiyuangong | Python | ||||||||||
| ruoru | Rust | ||||||||||
| shreymehul | C# | ||||||||||
| suxrobGM | C# | ||||||||||
| trung-hn | Python | ||||||||||
| varunu28 | Java | ||||||||||
| vli02 | C | ||||||||||
| vthwang | Java | ||||||||||
| XiaotaoGuo | C++ | ||||||||||
| YuriSpiridonov | Python | ||||||||||
| zfang399 | C++ | ||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||||||
| WalkCCC | C++, Python, Java | ||||||||||
| leetcode.ca | C++, Go, Java, JavaScript, Python, Rust, TypeScript | ||||||||||
| LeetcodeHelp | C++, Java, Python | ||||||||||
| MemoryLimitExceeded | Python, C++ | ||||||||||
| Progiez | C++, Java, Python | ||||||||||
| aylei | Rust | ||||||||||
| begeekmyfriend | C | ||||||||||
| BigEggStudy | C# | ||||||||||
| black-shadows | C++, C++ | ||||||||||
| chandansgowda | Python | ||||||||||
| charles-wangkai | Java | ||||||||||
| chenyanzhe | C++ | ||||||||||
| everthis | JavaScript | ||||||||||
| fartem | Ruby | ||||||||||
| fengvyi | C++ | ||||||||||
| fpdjsns | C++ | ||||||||||
| gaosq0604 | Python | ||||||||||
| halfrost | Go | ||||||||||
| JoshCrozier | JavaScript | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| lennylxx | C | ||||||||||
| linouk23 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| luangong | C++ | ||||||||||
| MacJim | C++ | ||||||||||
| qiyuangong | Python | ||||||||||
| ruoru | Rust | ||||||||||
| shreymehul | C# | ||||||||||
| suxrobGM | C# | ||||||||||
| trung-hn | Python | ||||||||||
| varunu28 | Java | ||||||||||
| vli02 | C | ||||||||||
| vthwang | Java | ||||||||||
| XiaotaoGuo | C++ | ||||||||||
| YuriSpiridonov | Python | ||||||||||
| zfang399 | C++ |
Videos
Similar Problems
- problem 54: Spiral Matrix
- problem 885: Spiral Matrix III
Solved On The Same Day
- problem 1: Two Sum
- problem 9: Palindrome Number
- problem 14: Longest Common Prefix
- problem 20: Valid Parentheses
- problem 26: Remove Duplicates from Sorted Array
- problem 27: Remove Element
- problem 83: Remove Duplicates from Sorted List
- problem 88: Merge Sorted Array
- problem 94: Binary Tree Inorder Traversal
- problem 100: Same Tree
- problem 104: Maximum Depth of Binary Tree
- problem 121: Best Time to Buy and Sell Stock
- problem 136: Single Number
- problem 141: Linked List Cycle
- problem 169: Majority Element
- problem 190: Reverse Bits
- problem 226: Invert Binary Tree
- problem 234: Palindrome Linked List
- problem 1114: Print in Order
- problem 3: Longest Substring Without Repeating Characters
- problem 7: Reverse Integer
- problem 8: String to Integer (atoi)
- problem 11: Container With Most Water
- problem 12: Integer to Roman
- problem 15: 3Sum
- problem 17: Letter Combinations of a Phone Number
- problem 22: Generate Parentheses
- problem 31: Next Permutation
- problem 36: Valid Sudoku
- problem 39: Combination Sum
- problem 40: Combination Sum II
- problem 45: Jump Game II
- problem 46: Permutations
- problem 47: Permutations II
- problem 48: Rotate Image
- problem 49: Group Anagrams
- problem 55: Jump Game
- problem 75: Sort Colors
- problem 77: Combinations
- problem 91: Decode Ways
- problem 95: Unique Binary Search Trees II
- problem 96: Unique Binary Search Trees
- problem 134: Gas Station
- problem 164: Maximum Gap
- problem 189: Rotate Array
- problem 215: Kth Largest Element in an Array
- problem 238: Product of Array Except Self
- problem 287: Find the Duplicate Number
- problem 322: Coin Change
- problem 347: Top K Frequent Elements
- problem 377: Combination Sum IV
- problem 438: Find All Anagrams in a String
- problem 474: Ones and Zeroes
- problem 518: Coin Change II
- problem 526: Beautiful Arrangement
- problem 763: Partition Labels
- problem 983: Minimum Cost For Tickets
- problem 994: Rotting Oranges
- problem 1027: Longest Arithmetic Subsequence
- problem 2140: Solving Questions With Brainpower
- problem 2466: Count Ways To Build Good Strings
- problem 4: Median of Two Sorted Arrays
- problem 41: First Missing Positive
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality