2639. Find the Width of Columns of a Grid
Problem Description
You are given a 2D integer matrix grid
with dimensions m x n
(m rows and n columns), where the matrix is 0-indexed.
The problem asks you to find the width of each column in the matrix. The width of a column is defined as the maximum length among all integers in that column.
To determine the length of an integer:
- For non-negative integers, the length equals the number of digits
- For negative integers, the length equals the number of digits plus 1 (to account for the negative sign)
For example:
- The integer
123
has length 3 - The integer
-10
has length 3 (2 digits + 1 for the negative sign) - The integer
5
has length 1
Given a matrix like grid = [[-10], [3], [12]]
:
- The only column contains values: -10, 3, and 12
- Their lengths are: 3, 1, and 2 respectively
- The width of this column is the maximum: 3
Your task is to return an integer array ans
of size n
(where n is the number of columns), where ans[i]
represents the width of the i-th column.
The solution uses zip(*grid)
to transpose the matrix and access columns directly, then calculates the maximum string length for each column using max(len(str(x)) for x in col)
. This efficiently computes the width by converting each number to a string and finding the longest one in each column.
Intuition
The key insight is that we need to process the matrix column by column rather than row by row, since we're looking for the maximum width within each column.
When we think about finding the "width" of a column, we're essentially asking: "What's the longest string representation among all numbers in this column?" This naturally leads us to consider converting each number to a string and measuring its length.
The string conversion approach len(str(x))
elegantly handles both positive and negative numbers. Python's str()
function automatically includes the negative sign for negative numbers, so -10
becomes "-10"
with length 3, while 10
becomes "10"
with length 2. This perfectly aligns with the problem's definition of length.
To work with columns efficiently, we can use Python's zip(*grid)
trick. The *
operator unpacks the rows of the grid, and zip
then groups elements by their column index. For example, if grid = [[1, 2], [3, 4], [5, 6]]
, then zip(*grid)
gives us [(1, 3, 5), (2, 4, 6)]
- effectively transposing the matrix and giving us direct access to columns.
Once we have each column as a sequence, finding the maximum width becomes straightforward: for each column, convert all numbers to strings, measure their lengths, and take the maximum. This can be expressed concisely with a list comprehension: [max(len(str(x)) for x in col) for col in zip(*grid)]
.
This approach is both intuitive and efficient - we visit each element exactly once, perform a simple string conversion, and maintain the maximum for each column.
Solution Approach
The solution follows a simulation approach where we calculate the width of each column by examining all elements within it.
Step 1: Matrix Transposition
We use zip(*grid)
to transpose the matrix and access columns directly. The *
operator unpacks the rows, and zip
groups elements by their position:
- Original matrix: rows are
[[a, b], [c, d], [e, f]]
- After
zip(*grid)
: columns become[(a, c, e), (b, d, f)]
Step 2: Width Calculation for Each Column
For each column obtained from the transposition, we:
- Convert each integer
x
to its string representation usingstr(x)
- Calculate the length of each string using
len(str(x))
- Find the maximum length within the column using
max(...)
Step 3: List Comprehension
The entire process is wrapped in a list comprehension:
[max(len(str(x)) for x in col) for col in zip(*grid)]
This creates a result array where each element represents the width of the corresponding column.
Example Walkthrough:
Consider grid = [[1, -22], [333, 4]]
:
zip(*grid)
gives us columns:[(1, 333), (-22, 4)]
- For first column
(1, 333)
:str(1)
= "1", length = 1str(333)
= "333", length = 3- Maximum = 3
- For second column
(-22, 4)
:str(-22)
= "-22", length = 3str(4)
= "4", length = 1- Maximum = 3
- Result:
[3, 3]
The time complexity is O(m × n)
where we visit each element once, and the space complexity is O(n)
for storing the result array.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with a concrete example to see how it works step by step.
Given: grid = [[10, -5, 0], [8, 234, -99]]
Step 1: Identify what we need
- We have a 2×3 matrix (2 rows, 3 columns)
- We need to find the width of each of the 3 columns
Step 2: Transpose the matrix using zip(*grid)
- Original rows:
[10, -5, 0]
and[8, 234, -99]
- After
zip(*grid)
:- Column 0:
(10, 8)
- Column 1:
(-5, 234)
- Column 2:
(0, -99)
- Column 0:
Step 3: Calculate width for each column
Column 0: (10, 8)
10
→str(10)
= "10" → length = 28
→str(8)
= "8" → length = 1- Maximum length = 2
Column 1: (-5, 234)
-5
→str(-5)
= "-5" → length = 2 (1 digit + 1 for negative sign)234
→str(234)
= "234" → length = 3- Maximum length = 3
Column 2: (0, -99)
0
→str(0)
= "0" → length = 1-99
→str(-99)
= "-99" → length = 3 (2 digits + 1 for negative sign)- Maximum length = 3
Step 4: Compile the result
- Column widths:
[2, 3, 3]
Solution code execution:
[max(len(str(x)) for x in col) for col in zip(*grid)]
This produces [2, 3, 3]
, which matches our manual calculation.
The key insight is that string conversion automatically handles the negative sign, making our width calculation straightforward and accurate.
Solution Implementation
1class Solution:
2 def findColumnWidth(self, grid: List[List[int]]) -> List[int]:
3 """
4 Find the width of each column in a grid.
5
6 The width of a column is defined as the maximum number of digits
7 among all integers in that column (including negative signs).
8
9 Args:
10 grid: A 2D list of integers
11
12 Returns:
13 A list where each element represents the width of the corresponding column
14 """
15 # Transpose the grid using zip(*grid) to get columns instead of rows
16 # For each column, find the maximum string length of its elements
17 # The string length accounts for negative signs in negative numbers
18 return [
19 max(len(str(element)) for element in column)
20 for column in zip(*grid)
21 ]
22
1class Solution {
2 /**
3 * Finds the maximum width needed for each column in a 2D grid.
4 * Width is determined by the number of digits (including negative sign) in each number.
5 *
6 * @param grid 2D integer array to analyze
7 * @return Array where each element represents the maximum width of the corresponding column
8 */
9 public int[] findColumnWidth(int[][] grid) {
10 // Get the number of columns from the first row
11 int numColumns = grid[0].length;
12
13 // Initialize result array to store maximum width for each column
14 int[] columnWidths = new int[numColumns];
15
16 // Iterate through each row in the grid
17 for (int[] currentRow : grid) {
18 // Check each element in the current row
19 for (int columnIndex = 0; columnIndex < numColumns; columnIndex++) {
20 // Convert the current number to string and get its length
21 // This handles negative numbers correctly (includes the minus sign)
22 int currentWidth = String.valueOf(currentRow[columnIndex]).length();
23
24 // Update the maximum width for this column if current width is larger
25 columnWidths[columnIndex] = Math.max(columnWidths[columnIndex], currentWidth);
26 }
27 }
28
29 return columnWidths;
30 }
31}
32
1class Solution {
2public:
3 vector<int> findColumnWidth(vector<vector<int>>& grid) {
4 // Get the number of columns in the grid
5 int numColumns = grid[0].size();
6
7 // Initialize result vector to store maximum width for each column
8 vector<int> columnWidths(numColumns);
9
10 // Iterate through each row in the grid
11 for (const auto& row : grid) {
12 // Check each element in the current row
13 for (int colIndex = 0; colIndex < numColumns; ++colIndex) {
14 // Convert the current number to string and get its length
15 int currentWidth = to_string(row[colIndex]).size();
16
17 // Update the maximum width for this column if current width is larger
18 columnWidths[colIndex] = max(columnWidths[colIndex], currentWidth);
19 }
20 }
21
22 // Return the array containing maximum width for each column
23 return columnWidths;
24 }
25};
26
1/**
2 * Finds the maximum width needed for each column in a 2D grid
3 * where width is determined by the string length of each number
4 * @param grid - 2D array of numbers
5 * @returns Array containing the maximum width for each column
6 */
7function findColumnWidth(grid: number[][]): number[] {
8 // Get the number of columns from the first row
9 const columnCount: number = grid[0].length;
10
11 // Initialize result array with zeros for each column
12 const columnWidths: number[] = new Array(columnCount).fill(0);
13
14 // Iterate through each row in the grid
15 for (const currentRow of grid) {
16 // Check each column in the current row
17 for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
18 // Calculate the width (string length) of the current number
19 const currentWidth: number = String(currentRow[columnIndex]).length;
20
21 // Update the maximum width for this column if current is larger
22 columnWidths[columnIndex] = Math.max(columnWidths[columnIndex], currentWidth);
23 }
24 }
25
26 return columnWidths;
27}
28
Time and Space Complexity
Time Complexity: O(m × n × log M)
The code iterates through all elements in the grid using zip(*grid)
which transposes the matrix, visiting each of the m × n
elements once. For each element x
, we convert it to a string using str(x)
, which takes O(log |x|)
time (the number of digits in the absolute value of x
). In the worst case, this is O(log M)
where M
is the absolute value of the maximum element. Therefore, the total time complexity is O(m × n × log M)
.
Space Complexity: O(m × n + log M)
The space complexity consists of:
O(m × n)
for storing the transposed matrix created byzip(*grid)
, which creates a new collection containing all elementsO(log M)
for the temporary string representation of each number during conversion- The output list of size
O(n)
is not counted as it's the required output
The dominant term is O(m × n)
, but if we only consider auxiliary space excluding the transposed matrix (treating the zip operation as iteration without storage), then the space complexity would be O(log M)
as stated in the reference answer, accounting only for the string conversion buffer.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Empty Grid Handling
The code will fail if the input grid is empty (either []
or contains empty rows like [[]]
). When zip(*grid)
is called on an empty grid, it returns an empty iterator, which could lead to unexpected behavior.
Problem Example:
grid = [] # or grid = [[]] # zip(*grid) returns empty, causing issues
Solution: Add an edge case check at the beginning:
def findColumnWidth(self, grid: List[List[int]]) -> List[int]:
if not grid or not grid[0]:
return []
return [max(len(str(element)) for element in column)
for column in zip(*grid)]
2. Confusion About Integer Zero
Developers might mistakenly think that 0
has a special case or no width, but 0
has a length of 1 just like any other single digit.
Clarification:
str(0)
= "0", length = 1str(-0)
= "0", length = 1 (Python treats -0 as 0)
3. Memory Overhead with Large Grids
Using zip(*grid)
creates tuples for all columns in memory simultaneously. For very large grids, this could cause memory issues.
Alternative Approach for Memory Optimization:
def findColumnWidth(self, grid: List[List[int]]) -> List[int]:
m, n = len(grid), len(grid[0])
result = [0] * n
for col in range(n):
for row in range(m):
result[col] = max(result[col], len(str(grid[row][col])))
return result
4. Assuming Regular Matrix Dimensions
The code assumes all rows have the same number of columns. If the grid is jagged (irregular), zip
will truncate to the shortest row length.
Problem Example:
grid = [[1, 2, 3], [4, 5]] # Irregular grid # zip(*grid) will only process first 2 columns
Solution: Validate input or handle irregular grids explicitly:
def findColumnWidth(self, grid: List[List[int]]) -> List[int]:
# Validate that all rows have the same length
if grid and len(set(len(row) for row in grid)) > 1:
raise ValueError("Irregular grid dimensions")
return [max(len(str(element)) for element in column)
for column in zip(*grid)]
A heap is a ...?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!