Open In App

Create a spiral matrix of N*M size from given array

Improve
Improve
Like Article
Like
Save
Share
Report

Given two values M and N, fill a matrix of size ‘M*N’ in a spiral (or circular) fashion (clockwise) with given array elements.

Examples:  

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

Input: M = 3, N = 4, arr =[1 8 6 3 8 6 1 6 3 2 5 3]
Output:  1 8 6 3
               2 5 3 8
              3 6 1 6 

 

Approach: The above problem can be solved using matrix traversal with special condition of turn.

The idea is to traverse the matrix in a direction and insert elements level by level, till a boundary or already filled cell is reached. As soon as such a wall is hit, make a right turn and continue the same.

Follow the below steps

  • Create a matrix of size m*n with value 0 in each cell initially
  • We will traverse a single loop from 1 to m*n
  • The direction of movement will be decided by a variable dir with 4 states:
    • 0 for Right,
    • 1 for Down,
    • 2 for Left, and
    • 3 for Up
  • The current cell of matrix is accessed using i and j as mat[i][j]
  • For each direction, the changes in i and j will be: 
     

       i  j

R:  0, 1

D:  1, 0

L:  0, -1

U: -1, 0

  • In each iteration:
    • Fill the mat[i][j] with value at current index of array, and increment current index by 1
    • Then check if the next step is out of bounds or a non-0 value which means already filled cell
    • If the above condition is true, change direction by 1 state
    • Shift the i and j pointer as per current direction

C++




// C++ program to fill a matrix with values
// from given array in spiral fashion.
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the current
// traversing pointer has gone out of bound
bool outOfBound(int i, int n)
{
    if (i < 0 || i >= n)
        return true;
    else
        return false;
}
 
// Function to generate
// m*n circular matrix
vector<vector<int> > spiralFill(
    vector<int>& arr,
    int m, int n)
{
 
    vector<vector<int> > mat(
        n, vector<int>(n, 0));
 
    // Direction:   R D L U
    // dir:         0 1 2 3
    int dir = 0;
 
    // Values to be filled
    // from arr.begin to arr.end
    int value = 0, end = arr.size();
 
    // i  j
    // R:  0, 1
    // D:  1, 0
    // L:  0, -1
    // U: -1, 0
    vector<vector<int> > dirArr;
    dirArr.push_back({ 0, 1 });
    dirArr.push_back({ 1, 0 });
    dirArr.push_back({ 0, -1 });
    dirArr.push_back({ -1, 0 });
 
    // Traversal pointers
    int i = 0, j = 0;
 
    while (value < end) {
 
        // Fill value
        mat[i][j] = arr[value];
 
        // Increment curr value
        value++;
 
        // Make a turn if next step
        // is boundary or a non-0 cell
        if (outOfBound(i + dirArr[dir][0], m)
            || outOfBound(j + dirArr[dir][1], n)
            || mat[i + dirArr[dir][0]]
                  [j + dirArr[dir][1]]
                   != 0) {
            dir = (dir + 1) % 4;
        }
 
        // Position of next cell
        i = i + dirArr[dir][0];
        j = j + dirArr[dir][1];
    }
 
    return mat;
}
 
// Driver program to test above functions
int main()
{
    int m = 3, n = 4;
    vector<int> arr
        = { 1, 8, 6, 3, 8, 6, 1,
            6, 3, 2, 5, 3 };
 
    vector<vector<int> > mat
        = spiralFill(arr, m, n);
 
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
            cout << mat[i][j] << " ";
        cout << endl;
    }
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.io.*;
 
class GFG {
 
  // Function to check if the current
  // traversing pointer has gone out of bound
  static boolean outOfBound(int i, int n)
  {
    if (i < 0 || i >= n)
      return true;
    else
      return false;
  }
 
  // Function to generate
  // m*n circular matrix
  static int[][] spiralFill(int[] arr, int m, int n)
  {
 
    int[][] mat = new int[n][n];
    for (int a = 0; a < n; a++) {
      for (int b = 0; b < n; b++) {
        mat[a][b] = 0;
      }
    }
 
    // Direction:   R D L U
    // dir:         0 1 2 3
    int dir = 0;
 
    // Values to be filled
    // from arr.begin to arr.end
    int value = 0, end = arr.length;
 
    // i  j
    // R:  0, 1
    // D:  1, 0
    // L:  0, -1
    // U: -1, 0
    int[][] dirArr = new int[4][ 2];
    dirArr[0][ 0] = 0;
    dirArr[0][1] = 1;
    dirArr[1][0] = 1;
    dirArr[1][1] = 0;
    dirArr[2][ 0] = 0;
    dirArr[2][1] = -1;
    dirArr[3][0] = -1;
    dirArr[3][1] = 0;
 
    // Traversal pointers
    int i = 0, j = 0;
 
    while (value < end) {
 
      // Fill value
      mat[i][ j] = arr[value];
 
      // Increment curr value
      value++;
 
      // Make a turn if next step
      // is boundary or a non-0 cell
      if (outOfBound(i + dirArr[dir][0], m)
          || outOfBound(j + dirArr[dir][1], n)
          || mat[i + dirArr[dir][0]]
          [j + dirArr[dir][ 1]]
          != 0) {
        dir = (dir + 1) % 4;
      }
 
      // Position of next cell
      i = i + dirArr[dir][ 0];
      j = j + dirArr[dir][1];
    }
 
    return mat;
  }
 
  // Driver program to test above functions
  public static void main (String[] args)
  {
    int m = 3, n = 4;
    int[] arr = { 1, 8, 6, 3, 8, 6, 1, 6, 3, 2, 5, 3 };
 
    int[][] mat = spiralFill(arr, m, n);
 
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        System.out.print(mat[i][ j] + " ");
      }
      System.out.println();
    }
  }
}
 
// This code is contributed by Potta Lokesh


Python3




# Python program to fill a matrix with values
# from given array in spiral fashion.
 
# Function to check if the current
# traversing pointer has gone out of bound
def outOfBound(i, n):
    if (i < 0 or i >= n):
        return True
    else:
        return False
 
# Function to generate
# m*n circular matrix
def spiralFill(arr, m, n):
 
    mat = [[0 for col in range(n)]for row in range(n)]
 
    # Direction: R D L U
    # dir: 0 1 2 3
    dir = 0
 
    # Values to be filled
    # from arr.begin to arr.end
    value,end = 0,len(arr)
 
    # i j
    # R: 0, 1
    # D: 1, 0
    # L: 0, -1
    # U: -1, 0
    dirArr = []
    dirArr.append([0, 1])
    dirArr.append([1, 0])
    dirArr.append([0, -1])
    dirArr.append([-1, 0])
 
    # Traversal pointers
    i,j = 0,0
 
    while (value < end):
 
        # Fill value
        mat[i][j] = arr[value]
 
        # Increment curr value
        value += 1
 
        # Make a turn if next step
        # is boundary or a non-0 cell
        if (outOfBound(i + dirArr[dir][0], m) or outOfBound(j + dirArr[dir][1], n) or mat[i + dirArr[dir][0]][j + dirArr[dir][1]]!= 0):
            dir = (dir + 1) % 4
 
        # Position of next cell
        i = i + dirArr[dir][0]
        j = j + dirArr[dir][1]
 
    return mat
 
# Driver program to test above functions
m,n = 3,4
arr = [1, 8, 6, 3, 8, 6, 1, 6, 3, 2, 5, 3]
 
mat = spiralFill(arr, m, n)
 
for i in range(m):
    for j in range(n):
        print(mat[i][j],end=" ")
    print()
 
# This code is contributed by shinjanpatra


C#




// C# program to fill a matrix with values
// from given array in spiral fashion.
 
using System;
class GFG {
 
  // Function to check if the current
  // traversing pointer has gone out of bound
  static bool outOfBound(int i, int n)
  {
    if (i < 0 || i >= n)
      return true;
    else
      return false;
  }
 
  // Function to generate
  // m*n circular matrix
  static int[, ] spiralFill(int[] arr, int m, int n)
  {
 
    int[, ] mat = new int[n, n];
    for (int a = 0; a < n; a++) {
      for (int b = 0; b < n; b++) {
        mat[a, b] = 0;
      }
    }
 
    // Direction:   R D L U
    // dir:         0 1 2 3
    int dir = 0;
 
    // Values to be filled
    // from arr.begin to arr.end
    int value = 0, end = arr.Length;
 
    // i  j
    // R:  0, 1
    // D:  1, 0
    // L:  0, -1
    // U: -1, 0
    int[, ] dirArr = new int[4, 2];
    dirArr[0, 0] = 0;
    dirArr[0, 1] = 1;
    dirArr[1, 0] = 1;
    dirArr[1, 1] = 0;
    dirArr[2, 0] = 0;
    dirArr[2, 1] = -1;
    dirArr[3, 0] = -1;
    dirArr[3, 1] = 0;
 
    // Traversal pointers
    int i = 0, j = 0;
 
    while (value < end) {
 
      // Fill value
      mat[i, j] = arr[value];
 
      // Increment curr value
      value++;
 
      // Make a turn if next step
      // is boundary or a non-0 cell
      if (outOfBound(i + dirArr[dir, 0], m)
          || outOfBound(j + dirArr[dir, 1], n)
          || mat[i + dirArr[dir, 0],
                 j + dirArr[dir, 1]]
          != 0) {
        dir = (dir + 1) % 4;
      }
 
      // Position of next cell
      i = i + dirArr[dir, 0];
      j = j + dirArr[dir, 1];
    }
 
    return mat;
  }
 
  // Driver program to test above functions
  public static void Main()
  {
    int m = 3, n = 4;
    int[] arr = { 1, 8, 6, 3, 8, 6, 1, 6, 3, 2, 5, 3 };
 
    int[, ] mat = spiralFill(arr, m, n);
 
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        Console.Write(mat[i, j] + " ");
      }
      Console.WriteLine();
    }
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
    // JavaScript program to fill a matrix with values
    // from given array in spiral fashion.
 
    // Function to check if the current
    // traversing pointer has gone out of bound
    const outOfBound = (i, n) => {
        if (i < 0 || i >= n)
            return true;
        else
            return false;
    }
 
    // Function to generate
    // m*n circular matrix
    const spiralFill = (arr, m, n) => {
 
        let mat = new Array(n).fill(0).map(() => new Array(n).fill(0));
 
        // Direction: R D L U
        // dir:         0 1 2 3
        let dir = 0;
 
        // Values to be filled
        // from arr.begin to arr.end
        let value = 0, end = arr.length;
 
        // i j
        // R: 0, 1
        // D: 1, 0
        // L: 0, -1
        // U: -1, 0
        let dirArr = [];
        dirArr.push([0, 1]);
        dirArr.push([1, 0]);
        dirArr.push([0, -1]);
        dirArr.push([-1, 0]);
 
        // Traversal pointers
        let i = 0, j = 0;
 
        while (value < end) {
 
            // Fill value
            mat[i][j] = arr[value];
 
            // Increment curr value
            value++;
 
            // Make a turn if next step
            // is boundary or a non-0 cell
            if (outOfBound(i + dirArr[dir][0], m)
                || outOfBound(j + dirArr[dir][1], n)
                || mat[i + dirArr[dir][0]]
                [j + dirArr[dir][1]]
                != 0) {
                dir = (dir + 1) % 4;
            }
 
            // Position of next cell
            i = i + dirArr[dir][0];
            j = j + dirArr[dir][1];
        }
 
        return mat;
    }
 
    // Driver program to test above functions
    let m = 3, n = 4;
    let arr = [1, 8, 6, 3, 8, 6, 1,
        6, 3, 2, 5, 3];
 
    let mat = spiralFill(arr, m, n);
 
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++)
            document.write(`${mat[i][j]} `);
        document.write("<br/>");
    }
 
// This code is contributed by rakeshsahni
</script>


 
 

Output

1 8 6 3 
2 5 3 8 
3 6 1 6 

 

Time Complexity: O(N*M)
Auxiliary Space: O(N*M)

 



Last Updated : 30 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads