Open In App

JavaScript Program to Print Given Matrix in Spiral Form

Write a JavaScript program to print a given 2D matrix in spiral form.

You are given a two-dimensional matrix of integers. Write a program to traverse the matrix starting from the top-left corner which moves right, bottom, left, and up in a spiral pattern until all the elements are visited. Let us understand it with the examples and figures given below:



Examples:

Example 1:

Input: matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
Output: [1 2 3 6 9 8 7 4 5]

Spiral Matrix Example-1

Example 2:



Input: matrix = [[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7]]
Output: [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]

Spiral Matrix Example-2

Method 1: Using Boundary Traversal Approach

To print a given matrix in a spiral form we initialize boundaries to track the matrix’s edges. Then iterate through the matrix, printing elements in a clockwise spiral pattern: top row, right column, bottom row, left column. Adjust boundaries after each step and continue until all elements are printed.

Example: Below is the implementation of the above approach:




// JavaScript code for the above approach
  
function printSpiral(matrix) {
    let result = [];
    let top = 0;
    let bottom = matrix.length - 1;
    let left = 0;
    let right = matrix[0].length - 1;
  
    // Loop while the elements 
    // are within the boundaries.
    while (top <= bottom
        && left <= right) {
        // Print top row
        for (let i = left;
            i <= right; i++) {
            result.push(matrix[top][i]);
        }
        // Move the top boundary down.
        top++;
  
        // Print right column
        for (let i = top;
            i <= bottom; i++) {
            result.push(matrix[i][right]);
        }
        // Move the right boundary to the left.
        right--;
  
        // Check if there are more rows
        if (top <= bottom) {
            // Print bottom row
            for (let i = right;
                i >= left; i--) {
                result.push(matrix[bottom][i]);
            }
            // Move the bottom boundary up.
            bottom--;
        }
  
        // Check if there are more columns
        if (left <= right) {
            // Print left column
            for (let i = bottom;
                i >= top; i--) {
                result.push(matrix[i][left]);
            }
            // Move the left boundary to the right.
            left++;
        }
    }
  
    // Print the result
    console.log(result.join(' '));
}
  
// Example
const matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16]
];
printSpiral(matrix);

Output
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10

Time Complexity: O(m * n): The time complexity of this code is O(m * n), where ‘m’ is the number of rows in the matrix, and ‘n’ is the number of columns in the matrix. This is because we visit each element in the matrix exactly once in a linear fashion.

Space Complexity: O(m * n): The space complexity is O(m * n) as well. The primary space consumption comes from the result array, which stores all the elements of the matrix in spiral order. The size of this array is directly proportional to the number of elements in the matrix, which is ‘m * n’.

Method 2: Using Simulation Approach

Example: Below is the implementation of the above approach:




// JavaScript code for the above approach
  
function spiralOrder(matrix) {
    let result = [];
  
    if (matrix.length === 0) {
        return result;
    }
  
    let N = matrix.length;
    let M = matrix[0].length;
    // Create a visited matrix
    let vis = new Array(N);
    for (let n = 0; n < N; n++) {
        vis[n] = new Array(M).fill(false);
    }
  
    let dx = [0, 1, 0, -1];
    let dy = [1, 0, -1, 0];
    let n = 0, m = 0, d = 0;
  
    // Traverse through the matrix
    for (let i = 0; i < N * M; i++) {
        result.push(matrix[n][m]);
        vis[n][m] = true;
  
        // Calculate the next 
        // cell's position
        let nrow = n + dx[d];
        let ncol = m + dy[d];
  
        // Check the valid positions 
        // of the cell
        if (nrow >= 0 && nrow < N
            && ncol >= 0 && ncol < M
            && !vis[nrow][ncol]
        ) {
            n = nrow;
            m = ncol;
        } else {
            // Perform a clockwise 
            // turn to change direction
            d = (d + 1) % 4;
            n += dx[d];
            m += dy[d];
        }
    }
  
    return result.join(' ');
}
  
// Example
const matrix = [
    [1, 2, 3, 4],
    [12, 13, 14, 5],
    [11, 16, 15, 6],
    [10, 9, 8, 7],
];
  
let spiralResult = spiralOrder(matrix);
console.log(spiralResult);

Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Time Complexity: O(N * M).

Space Complexity: O(N * M).

Method 3: Using Recursion in JavaScript

Example: Below is the implementation of the above approach:




// JavaScript code for the above approach
  
function printSpiralRecursive(matrix, k, m, l, n) {
    // Base case
    if (k > m || l > n) {
        return '';
    }
  
    let result = '';
    // Print the top row from left to right
    for (let i = l; i <= n; i++) {
        result += matrix[k][i] + ' ';
    }
    // Increment the row index from start
    k++;
  
    // Print the right column from top to bottom
    for (let i = k; i <= m; i++) {
        result += matrix[i][n] + ' ';
    }
    // Decrement the column index from end
    n--;
  
    // Check if there is a bottom row to print
    if (k <= m) {
        for (let i = n; i >= l; i--) {
            result += matrix[m][i] + ' ';
        }
        // Decrement the row index from end
        m--;
    }
  
    // Check if there is a left column to print
    if (l <= n) {
        for (let i = m; i >= k; i--) {
            result += matrix[i][l] + ' ';
        }
        // Increment the column index from start
        l++;
    }
  
    // Recursive Call
    return result +
        printSpiralRecursive(matrix, k, m, l, n);
}
  
// Function to print the matrix in spiral form
function printSpiral(matrix) {
    const rows =
        matrix.length;
    const columns =
        matrix[0].length;
    const spiralResult =
        printSpiralRecursive(matrix, 0, rows - 1,
            0, columns - 1);
    console.log(spiralResult);
}
  
// Example
const matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];
  
printSpiral(matrix);

Output
1 2 3 6 9 8 7 4 5 

Time Complexity: O(N*M). To traverse the entire matrix O(N*M) time is required.

Space Complexity: O(1). As we do not use any external data structure here, there is constant space. But obviously the algorithm will consume a recursive stack space of O(n).

Method 4: Using Depth First Search (DFS)

Example: Below is the implementation of the above approach:




// JavaScript code for the above approach
  
function spiralDFS(matrix) {
    const N = matrix.length;
    const M = matrix[0].length;
  
    // Initialize a visited array 
    let vis = new Array(N);
    for (let n = 0; n < N; n++) {
        vis[n] = new Array(M).fill(false);
    }
  
    // Row and column directions for 
    // right, down, left, and up
    const dx = [0, 1, 0, -1];
    const dy = [1, 0, -1, 0];
  
    let i = 0;
    let row = 0;
    let col = 0;
  
    const result = [];
  
    // DFS function
    function dfs(row, col) {
        // Base case: Check if the current 
        // cell is within bounds and unvisited
        if (row < 0 || row >= N ||
            col < 0 || col >= M ||
            vis[row][col]) {
            return;
        }
  
        // Mark the cell as visited 
        // and add it to the result
        result.push(matrix[row][col]);
        vis[row][col] = true;
  
        // Calculate the next row and column
        const nrow = row + dx[i];
        const ncol = col + dy[i];
  
        // Recursively call DFS with the new indices
        dfs(nrow, ncol);
  
        // If DFS completes in the current 
        // direction, change direction clockwise
        if (nrow < 0 || nrow >= N ||
            ncol < 0 || ncol >= M ||
            vis[nrow][ncol]) {
            i = (i + 1) % 4;
            const nrow = row + dx[i];
            const ncol = col + dy[i];
            dfs(nrow, ncol);
        }
    }
  
    // Start DFS from the top-left 
    // corner of the matrix
    dfs(row, col);
  
    console.log(result.join(' '));
}
  
// Example
const matrix = [
    [1, 2, 3],
    [6, 5, 7],
    [4, 8, 11],
    [12, 0, 16]
];
  
spiralDFS(matrix);

Output
1 2 3 7 11 16 0 12 4 6 5 8

Time Complexity: O(N*M) To traverse the entire matrix O(m*n) time is required.

Space Complexity: O(N*M) We use an external data structure here, which is a 2D visited matrix. Also, the algorithm will consume a recursive stack space.


Article Tags :