📜  从给定数组创建一个 N*M 大小的螺旋矩阵

📅  最后修改于: 2022-05-13 01:56:07.634000             🧑  作者: Mango

从给定数组创建一个 N*M 大小的螺旋矩阵

给定两个值MN ,用给定的数组元素以螺旋(或圆形)方式(顺时针)填充大小为“ M * N ”的矩阵。

例子:

方法:上述问题可以通过特殊条件下的矩阵遍历来解决。

请按照以下步骤操作

  • 最初在每个单元格中创建一个大小为 m*n 的矩阵,其值为 0
  • 我们将遍历从 1 到 m*n 的单个循环
  • 移动方向将由具有 4 个状态的变量 dir 决定:
    • 0 代表右,
    • 1 表示向下,
    • 2 代表左,和
    • 3 向上
  • 使用 i 和 j 作为 mat[i][j] 访问矩阵的当前单元格
  • 对于每个方向,i 和 j 的变化将是:
  • 在每次迭代中:
    • 用数组当前索引处的值填充 mat[i][j],并将当前索引增加 1
    • 然后检查下一步是否超出范围或非 0 值,这意味着已填充单元格
    • 如果上述条件为真,则将方向改变 1 个状态
    • 根据当前方向移动 i 和 j 指针
C++
// C++ program to fill a matrix with values
// from given array in spiral fashion.
 
#include 
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 > spiralFill(
    vector& arr,
    int m, int n)
{
 
    vector > mat(
        n, vector(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 > 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 arr
        = { 1, 8, 6, 3, 8, 6, 1,
            6, 3, 2, 5, 3 };
 
    vector > 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



输出
1 8 6 3 
2 5 3 8 
3 6 1 6 

时间复杂度:O(N*M)
辅助空间:O(N*M)