从给定数组创建一个 N*M 大小的螺旋矩阵
给定两个值M和N ,用给定的数组元素以螺旋(或圆形)方式(顺时针)填充大小为“ M * N ”的矩阵。
例子:
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
方法:上述问题可以通过特殊条件下的矩阵遍历来解决。
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.
请按照以下步骤操作
- 最初在每个单元格中创建一个大小为 m*n 的矩阵,其值为 0
- 我们将遍历从 1 到 m*n 的单个循环
- 移动方向将由具有 4 个状态的变量 dir 决定:
- 0 代表右,
- 1 表示向下,
- 2 代表左,和
- 3 向上
- 使用 i 和 j 作为 mat[i][j] 访问矩阵的当前单元格
- 对于每个方向,i 和 j 的变化将是:
i j
R: 0, 1
D: 1, 0
L: 0, -1
U: -1, 0
- 在每次迭代中:
- 用数组当前索引处的值填充 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)