Flatten 2D Vector

Updated on 29 May, 2025
Flatten 2D Vector header image

Problem Statement

Design a class Vector2D to flatten and iterate over a 2-dimensional vector (nested list). The iterator should provide the following operations:

  • next() – Returns the current element and advances the iterator.
  • hasNext() – Returns true if there are remaining elements to iterate through; otherwise, false.

Each inner list may be of different lengths, including empty. The iterator should correctly handle these edge cases.

Examples

Example 1

Input:

["Vector2D", "next", "next", "next", "hasNext", "hasNext", "next", "hasNext"]
[[[[1, 2], [3], [4]]], [], [], [], [], [], [], []]

Output:

[null, 1, 2, 3, true, true, 4, false]

Explanation:

Vector2D vector2D = new Vector2D([[1, 2], [3], [4]]);
vector2D.next();      // returns 1
vector2D.next();      // returns 2
vector2D.next();      // returns 3
vector2D.hasNext();   // returns true
vector2D.hasNext();   // returns true
vector2D.next();      // returns 4
vector2D.hasNext();   // returns false

Constraints

  • 0 <= vec.length <= 200
  • 0 <= vec[i].length <= 500
  • -500 <= vec[i][j] <= 500
  • Up to 10^5 calls to next() and hasNext() may be made.

Approach and Intuition

To manage iteration across a variable-length 2D vector efficiently, a dual-pointer approach is used:

1. Initialization

Maintain two indices:

  • outer – tracks the current row in the 2D list.
  • inner – tracks the current element within the current row.

This approach efficiently skips empty rows without flattening the entire list upfront.

2. hasNext() Method

Before attempting to access any element:

  • Check whether the current outer index is within bounds.
  • If the current row is empty or the inner index exceeds the row’s length, advance outer and reset inner.
  • Repeat this until a valid position is found or the end of the structure is reached.

3. next() Method

  • Always call hasNext() first to ensure a valid element exists.
  • Return the current element and advance the inner index.

Benefits

  • Avoids unnecessary memory use — does not pre-flatten the entire structure.
  • Time-efficient — each element and sublist is processed at most once.
  • Correctly handles empty lists, variable-length rows, and large volumes of method calls.

This structure ensures robust and responsive iterator behavior, even for edge cases like multiple empty inner lists or dynamic iterations at runtime.

Solutions

  • Java
java
import java.util.NoSuchElementException;

class MatrixIterator {

    private int[][] matrix;
    private int rowPointer = 0;
    private int colPointer = 0;

    public MatrixIterator(int[][] m) {
        matrix = m;
    }

    private void skipToValid() {
        while (rowPointer < matrix.length && colPointer == matrix[rowPointer].length) {
            colPointer = 0;
            rowPointer++;
        }
    }

    public int next() {
        if (!hasNext()) throw new NoSuchElementException();
        return matrix[rowPointer][colPointer++];
    }

    public boolean hasNext() {
        skipToValid();
        return rowPointer < matrix.length;
    }
}

The provided Java code implements a custom iterator for a 2D matrix called MatrixIterator. This implementation allows iteration over a two-dimensional array in a flat, sequential manner.

  • Create an instance of MatrixIterator by passing a 2D integer array to its constructor.
  • Utilize the next() method to retrieve the next integer from the 2D array. If there are no more elements to return, this method throws a NoSuchElementException.
  • Check if there are more elements to iterate over in the matrix using the hasNext() method. This function moves the internal pointers to the next valid element, if necessary, ensuring that the next() call will be valid.
  • The skipToValid() method is a private helper function used within hasNext(). It adjusts rowPointer and colPointer to skip empty rows, ensuring that hasNext() and next() always point to a valid element or end the iteration gracefully when all elements are exhausted.

This implementation is an efficient way to "flatten" the 2D matrix traversal, abstracting the complexity of handling row and column transitions behind the simple interface of an iterator.

Comments

No comments yet.