Facebook Pixel

2022. Convert 1D Array Into 2D Array

EasyArrayMatrixSimulation
Leetcode Link

Problem Description

You are given a 1-dimensional array called original and two integers m and n. Your task is to reshape this 1D array into a 2D array with m rows and n columns.

The reshaping should follow these rules:

  • Elements at indices 0 to n-1 from original should form the first row
  • Elements at indices n to 2*n-1 should form the second row
  • Elements at indices 2*n to 3*n-1 should form the third row
  • This pattern continues until all elements are placed

The transformation is only possible if the total number of elements in original equals m * n. If this condition is not met, return an empty 2D array.

For example, if original = [1,2,3,4], m = 2, and n = 2:

  • First row: elements at indices 0-1 → [1,2]
  • Second row: elements at indices 2-3 → [3,4]
  • Result: [[1,2],[3,4]]

The solution checks if m * n equals the length of original. If not, it returns an empty array. Otherwise, it uses list comprehension to slice the original array into chunks of size n, creating each row of the 2D array by taking elements from index i to i+n for each starting position i that is a multiple of n.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is recognizing this as a reshape operation where we're taking a linear sequence and arranging it into a grid format. Think of it like arranging a single line of people into rows for a group photo.

First, we need to verify if the reshape is even possible. Since we need to use all elements from the original array to fill an m × n grid completely, the total number of elements must match exactly. This gives us our validation condition: m * n == len(original).

Once we know the reshape is valid, the transformation becomes straightforward. We need to take consecutive chunks of n elements from the original array to form each row. Why chunks of size n? Because each row in our target 2D array has exactly n columns.

The pattern emerges clearly:

  • Row 0: elements from index 0 to n-1
  • Row 1: elements from index n to 2n-1
  • Row 2: elements from index 2n to 3n-1
  • Row i: elements from index i*n to (i+1)*n-1

This naturally leads to a slicing approach where we iterate through the original array in steps of n, taking n elements at each step. Python's list slicing original[i:i+n] perfectly captures this chunk extraction, and we can generate all rows using a list comprehension that starts at indices 0, n, 2n, ... up to m*n.

The elegance of this solution lies in recognizing that reshaping is simply a matter of reinterpreting the same data with different indexing boundaries, without any complex transformations needed.

Solution Approach

The implementation follows a simulation approach where we directly construct the 2D array by slicing the original array into appropriate chunks.

Step 1: Validation Check

First, we verify if the transformation is possible by checking if m * n != len(original). If the product of dimensions doesn't equal the array length, we immediately return an empty list [] since it's impossible to completely fill an m × n matrix with the given elements.

if m * n != len(original):
    return []

Step 2: Array Construction Using List Comprehension

Once validation passes, we construct the 2D array using Python's list comprehension with slicing:

return [original[i : i + n] for i in range(0, m * n, n)]

Let's break down this comprehension:

  • range(0, m * n, n) generates starting indices: 0, n, 2n, 3n, ... up to (m-1) * n
  • For each starting index i, we extract a slice original[i : i + n] which gives us exactly n consecutive elements
  • Each slice becomes one row in our result

Why This Works:

The algorithm leverages the fact that in row-major order (which is how we're filling the 2D array), the element at position (row, col) in the 2D array corresponds to index row * n + col in the 1D array. By taking slices of size n starting at multiples of n, we're essentially reversing this mapping.

Time and Space Complexity:

  • Time Complexity: O(m * n) as we need to process each element once
  • Space Complexity: O(1) extra space (not counting the output array which is required by the problem)

The beauty of this solution lies in its simplicity - we're not manually tracking row and column indices or using nested loops. Instead, we let Python's slicing handle the chunking operation efficiently.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example with original = [1,2,3,4,5,6], m = 2, and n = 3.

Step 1: Validation Check

  • Calculate m * n = 2 * 3 = 6
  • Check if 6 == len([1,2,3,4,5,6])6 == 6
  • Since they're equal, we can proceed with the transformation

Step 2: Determine Row Starting Indices

  • We need to create 2 rows (m = 2), each with 3 elements (n = 3)
  • Using range(0, m * n, n)range(0, 6, 3) generates indices: [0, 3]
  • These are the starting positions for each row in the original array

Step 3: Extract Rows Using Slicing

  • First iteration (i = 0):

    • Extract original[0:0+3]original[0:3][1,2,3]
    • This becomes our first row
  • Second iteration (i = 3):

    • Extract original[3:3+3]original[3:6][4,5,6]
    • This becomes our second row

Step 4: Combine Results

  • The list comprehension collects these slices: [[1,2,3], [4,5,6]]

Visual Representation:

Original: [1, 2, 3, 4, 5, 6]
           ↓  ↓  ↓  ↓  ↓  ↓
Row 0:    [1, 2, 3]
Row 1:             [4, 5, 6]

Result: [[1, 2, 3],
         [4, 5, 6]]

The algorithm efficiently transforms the 1D array into a 2×3 matrix by taking consecutive chunks of 3 elements, demonstrating how the slicing approach naturally handles the row-wise reshaping.

Solution Implementation

1class Solution:
2    def construct2DArray(self, original: List[int], m: int, n: int) -> List[List[int]]:
3        # Check if the total elements match the required matrix dimensions
4        if m * n != len(original):
5            return []
6      
7        # Create 2D array by slicing the original array into rows of length n
8        # Each row starts at index i and ends at index i+n
9        result = []
10        for i in range(0, m * n, n):
11            row = original[i:i + n]
12            result.append(row)
13      
14        return result
15```
16
17Alternative implementation using list comprehension (more concise):
18
19```python3
20class Solution:
21    def construct2DArray(self, original: List[int], m: int, n: int) -> List[List[int]]:
22        # Validate that the 1D array can form an m x n matrix
23        if m * n != len(original):
24            return []
25      
26        # Construct the 2D array by slicing original into n-sized chunks
27        # i iterates from 0 to m*n with step size n (0, n, 2n, ...)
28        return [original[i:i + n] for i in range(0, m * n, n)]
29
1class Solution {
2    /**
3     * Converts a 1D array into a 2D array with specified dimensions.
4     * 
5     * @param original The input 1D array to be converted
6     * @param m The number of rows in the resulting 2D array
7     * @param n The number of columns in the resulting 2D array
8     * @return A 2D array with dimensions m x n, or empty array if conversion is impossible
9     */
10    public int[][] construct2DArray(int[] original, int m, int n) {
11        // Check if the total elements match the required 2D array dimensions
12        if (m * n != original.length) {
13            // Return empty 2D array if dimensions don't match
14            return new int[0][0];
15        }
16      
17        // Initialize the result 2D array with specified dimensions
18        int[][] resultArray = new int[m][n];
19      
20        // Iterate through each row
21        for (int row = 0; row < m; row++) {
22            // Iterate through each column in the current row
23            for (int col = 0; col < n; col++) {
24                // Map 1D array index to 2D array position
25                // Formula: row * numberOfColumns + column
26                resultArray[row][col] = original[row * n + col];
27            }
28        }
29      
30        // Return the constructed 2D array
31        return resultArray;
32    }
33}
34
1class Solution {
2public:
3    vector<vector<int>> construct2DArray(vector<int>& original, int m, int n) {
4        // Check if the total elements match the required 2D array dimensions
5        // If not, return an empty 2D array
6        if (m * n != original.size()) {
7            return {};
8        }
9      
10        // Initialize the result 2D array with m rows and n columns
11        vector<vector<int>> result(m, vector<int>(n));
12      
13        // Iterate through each row
14        for (int row = 0; row < m; ++row) {
15            // Iterate through each column in the current row
16            for (int col = 0; col < n; ++col) {
17                // Map the 1D array index to 2D array position
18                // Formula: 1D index = row * number_of_columns + column
19                result[row][col] = original[row * n + col];
20            }
21        }
22      
23        // Return the constructed 2D array
24        return result;
25    }
26};
27
1/**
2 * Converts a 1D array into a 2D array with specified dimensions
3 * @param original - The input 1D array to be converted
4 * @param m - Number of rows in the resulting 2D array
5 * @param n - Number of columns in the resulting 2D array
6 * @returns A 2D array with m rows and n columns, or empty array if impossible
7 */
8function construct2DArray(original: number[], m: number, n: number): number[][] {
9    // Check if the total elements match the required dimensions
10    if (m * n !== original.length) {
11        return [];
12    }
13  
14    // Initialize the result 2D array
15    const result: number[][] = [];
16  
17    // Iterate through the original array in chunks of size n
18    for (let startIndex = 0; startIndex < m * n; startIndex += n) {
19        // Extract a row of n elements and add to result
20        result.push(original.slice(startIndex, startIndex + n));
21    }
22  
23    return result;
24}
25

Time and Space Complexity

Time Complexity: O(m × n)

The time complexity is determined by the list comprehension that creates the 2D array. The comprehension iterates m times (once for each row), and for each iteration, it performs a slice operation original[i : i + n] which takes O(n) time to copy n elements. Therefore, the total time complexity is O(m × n), which equals O(len(original)) since m × n = len(original) when a valid 2D array can be constructed.

Space Complexity: O(1) (excluding the output array)

If we don't count the space required for the output array (which is necessary for the answer), the space complexity is O(1). The algorithm only uses a constant amount of extra space for the loop variable i in the list comprehension. The slicing operation creates new lists, but these are part of the required output rather than auxiliary space used by the algorithm itself.

If we include the output array, the space complexity would be O(m × n) to store the resulting 2D array.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Off-by-One Errors in Range Calculation

A common mistake is using range(0, m, n) instead of range(0, m * n, n). This would only generate m/n rows instead of m rows.

Incorrect:

return [original[i:i + n] for i in range(0, m, n)]  # Wrong!

Correct:

return [original[i:i + n] for i in range(0, m * n, n)]

2. Forgetting the Validation Check

Omitting the dimension validation can lead to incorrect results when the array cannot perfectly form the desired matrix. Without this check, you might get:

  • Incomplete rows if len(original) < m * n
  • Missing elements if len(original) > m * n

Solution: Always validate first:

if m * n != len(original):
    return []

3. Using Nested Loops with Index Calculation Errors

When using nested loops, a frequent error is incorrectly calculating the 1D index from 2D coordinates:

Incorrect:

result = []
for row in range(m):
    current_row = []
    for col in range(n):
        index = row + col * m  # Wrong formula!
        current_row.append(original[index])
    result.append(current_row)

Correct:

result = []
for row in range(m):
    current_row = []
    for col in range(n):
        index = row * n + col  # Correct: row * columns + col
        current_row.append(original[index])
    result.append(current_row)

4. Modifying the Original Array

Some might try to use pop() or similar destructive operations on the original array:

Problematic:

result = []
for _ in range(m):
    row = []
    for _ in range(n):
        row.append(original.pop(0))  # Modifies original and O(n) per pop!
    result.append(row)

This approach has two issues:

  • It modifies the input array (usually undesirable)
  • Using pop(0) is O(n) for each operation, making the overall complexity O(m * n²)

Better approach: Use slicing which doesn't modify the original and maintains O(m * n) complexity.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which data structure is used in a depth first search?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More