我如何以螺旋顺序打印一个5×5的二维数组?
是否有任何公式可以让我按照螺旋顺序打印任何大小的数组?
我如何以螺旋顺序打印一个5×5的二维数组?
是否有任何公式可以让我按照螺旋顺序打印任何大小的数组?
public static void printMatrixInSpiral(int[][] mat){
if(mat.length == 0|| mat[0].length == 0){
/* empty matrix */
return;
}
StringBuffer str = new StringBuffer();
int counter = mat.length * mat[0].length;
int startRow = 0;
int endRow = mat.length-1;
int startCol = 0;
int endCol = mat[0].length-1;
boolean moveCol = true;
boolean leftToRight = true;
boolean upDown = true;
while(counter>0){
if(moveCol){
if(leftToRight){
/* printing entire row left to right */
for(int i = startCol; i <= endCol ; i++){
str.append(mat[startRow][i]);
counter--;
}
leftToRight = false;
moveCol = false;
startRow++;
}
else{
/* printing entire row right to left */
for(int i = endCol ; i >= startCol ; i--){
str.append(mat[endRow][i]);
counter--;
}
leftToRight = true;
moveCol = false;
endRow--;
}
}
else
{
if(upDown){
/* printing column up down */
for(int i = startRow ; i <= endRow ; i++){
str.append(mat[i][endCol]);
counter--;
}
upDown = false;
moveCol = true;
endCol--;
}
else
{
/* printing entire col down up */
for(int i = endRow ; i >= startRow ; i--){
str.append(mat[i][startCol]);
counter--;
}
upDown = true;
moveCol = true;
startCol++;
}
}
}
System.out.println(str.toString());
}
思路:
我们需要按螺旋的方式在四个不同的方向上遍历。当一个螺旋层结束后,我们需要在矩阵内部遍历一次。因此,总共需要5个循环,4个循环用于像螺旋一样遍历,1个循环用于遍历各层。
public void printSpiralForm(int[][] a, int length)
{
for( int i = 0 , j = length-1 ; i < j ; i++ , j-- )
{
for( int k = i ; k < j ; k++ )
{
System.out.print( a[i][k] + " " ) ;
}
for( int k = i ; k < j ; k++ )
{
System.out.print(a[k][j] + " ");
}
for( int k = j ; k > i ; k-- )
{
System.out.print(a[j][k] + " ") ;
}
for( int k = j ; k > i ; k-- )
{
System.out.print( a[k][i] + " " ) ;
}
}
if ( length % 2 == 1 )
{
System.out.println( a[ length/2 ][ length/2 ] ) ;
}
}
{}
,代码将变得更整洁,就像这里:http://www.crazyforcode.com/print-square-matrix-spiral-form/ - Jackson Tale复杂度: 单次遍历
O(n)
请允许我添加一个复杂度为O(n)
的单循环答案。我观察到在矩阵的左-右和右-左遍历过程中,行主索引分别增加和减少1。同样地,在上-下和下-上遍历中,n_cols
会增加和减少。因此,我制定了一个算法。例如,给定一个(3x5)矩阵,其条目为行主索引,则打印输出为:1,2,3,4,5,10,15,14,13,12,11,6,7,8,9
。
------->(+1)
^ 1 2 3 4 5 |
(+n_cols) | 6 7 8 9 10 | (-n_cols)
| 11 12 13 14 15
(-1)<-------
#include <iostream>
using namespace std;
int main() {
// your code goes here
bool leftToRight=true, topToBottom=false, rightToLeft=false, bottomToTop=false;
int idx=0;
int n_rows = 3;
int n_cols = 5;
int cnt_h = n_cols, cnt_v = n_rows, cnt=0;
int iter=1;
for (int i=0; i <= n_rows*n_cols + (n_rows - 1)*(n_cols - 1)/2; i++){
iter++;
if(leftToRight){
if(cnt >= cnt_h){
cnt_h--; cnt=0;
leftToRight = false; topToBottom = true;
//cout << "Iter: "<< iter << " break_leftToRight"<<endl;
}else{
cnt++;
idx++;
//cout << "Iter: "<< iter <<" idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
cout<< idx << endl;
}
}else if(topToBottom){
if(cnt >= cnt_v-1){
cnt_v--; cnt=0;
leftToRight = false; topToBottom = false; rightToLeft=true;
//cout << "Iter: "<< iter << " break_topToBottom"<<endl;
}else{
cnt++;
idx+=n_cols;
//cout << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
cout << idx <<endl;
}
}else if(rightToLeft){
if(cnt >= cnt_h){
cnt_h--; cnt=0;
leftToRight = false; topToBottom = false; rightToLeft=false; bottomToTop=true;
//cout << "Iter: "<< iter << " break_rightToLeft"<<endl;
//cout<< idx << endl;
}else{
cnt++;
idx--;
//cout << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_h: "<< cnt_h<< endl;
cout << idx <<endl;
}
}else if(bottomToTop){
if(cnt >= cnt_v-1){
cnt_v--; cnt=0;
leftToRight = true; topToBottom = false; rightToLeft=false; bottomToTop=false;
//cout << "Iter: "<< iter << " break_bottomToTop"<<endl;
}else{
cnt++;
idx-=n_cols;
//cout << "Iter: "<< iter << " idx: " << idx << " cnt: "<< cnt << " cnt_v: "<< cnt_h<< endl;
cout<< idx << endl;
}
}
//cout << i << endl;
}
return 0;
}
void slashTransposeFlip(int[][] m){
if( m.length * m[0].length == 1){ //only one element left
System.out.print(m[0][0]);
}else{
//print the top row
for(int a:m[0]){System.out.print(a+" ");}
//slash the top row from the matrix.
int[][] n = Arrays.copyOfRange(m,1,m.length);
int[][] temp = n;
int rows = temp.length;
int columns = temp[0].length;
//invert rows and columns and create new array
n = new int[columns][rows];
//transpose
for(int x=0;x<rows;x++)
for(int y=0;y<columns;y++)
n[y][x] = temp[x][y];
//flipping time
for (int i = 0; i < n.length / 2; i++) {
int[] t = n[i];
n[i] = n[n.length - 1 - i];
n[n.length - 1 - i] = t;
}
//recursively call again the reduced matrix.
slashTransposeFlip(n);
}
}
class Spiral:
def spiralOrder(self, A):
result = []
c = []
c.append(A[0])
b = A[1:]
while len(b) > 0:
b = self.rotate(b)
c.append(b[0])
b = b[1:]
for item in c:
for fitem in item:
print fitem,
result.append(fitem)
return result
def rotate(self,a):
b = []
l = zip(*a)
for i in xrange(len(l)-1,-1,-1):
b.append(list(l[i]))
return b
if __name__ == '__main__':
a = [[1, 2, 3,3], [4, 5, 6,6], [7, 8, 9,10]]
s = Spiral()
s.spiralOrder(a)
function spiral(a) {
var s = [];
while (a.length) {
// concat 1st row, push last cols, rotate 180 (reverse inner/outer)...
s = s.concat(a.shift());
a = a
.map(function(v) {
s.push(v.pop());
return v.reverse();
})
.reverse();
}
return s;
}
var arr = [
[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7]
];
console.log(spiral(arr));// -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
arr = [
[0, 1, 2, 3, 4],
[15, 16, 17, 18, 5],
[14, 23, 24, 19, 6],
[13, 22, 21, 20, 7],
[12, 11, 10, 9, 8]
];
console.log(spiral(arr));// -> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
这是我的实现:
public static void printMatrix(int matrix[][], int M, int N){
int level = 0;
int min = (M < N) ? M:N;
System.out.println();
while(level <= min/2){
for(int j = level; j < N - level - 1; j++){
System.out.print(matrix[level][j] + "\t");
}
for(int i = level; i < M - level - 1; i++) {
System.out.print(matrix[i][N - level - 1] + "\t");
}
for(int j = N - level - 1; j > level; j--){
System.out.print(matrix[M - level - 1][j] + "\t");
}
for(int i = M - level - 1; i > level; i-- ){
System.out.print(matrix[i][level] + "\t");
}
level++;
}
}
matrix={{1}}, M=1, N=1
时会失败。在这种情况下,将什么都不会输出。 - wenqiang如果要打印二维矩阵,可以将矩阵视为由矩形和/或线条组成,其中较小的矩形适合较大的矩形中。取形成一个矩形的矩阵边界进行打印,从每层的左上角元素开始每次打印;完成这个步骤后,进入下一层较小矩形的内部。如果没有矩形,则应该打印一条横线或竖线。我已经附上了示例矩阵的代码,希望对你有所帮助。
#include <stdio.h>
int a[2][4] = { 1, 2 ,3, 44,
8, 9 ,4, 55 };
void print(int, int, int, int);
int main() {
int row1, col1, row2, col2;
row1=0;
col1=0;
row2=1;
col2=3;
while(row2>=row1 && col2>=col1)
{
print(row1, col1, row2, col2);
row1++;
col1++;
row2--;
col2--;
}
return 0;
}
void print(int row1, int col1, int row2, int col2) {
int i=row1;
int j=col1;
/* This is when single horizontal line needs to be printed */
if( row1==row2 && col1!=col2) {
for(j=col1; j<=col2; j++)
printf("%d ", a[i][j]);
return;
}
/* This is when single vertical line needs to be printed */
if( col1==col2 && row1!=row2) {
for(i=row1; j<=row2; i++)
printf("%d ", a[i][j]);
return;
}
/* This is reached when there is a rectangle to be printed */
for(j=col1; j<=col2; j++)
printf("%d ", a[i][j]);
for(j=col2,i=row1+1; i<=row2; i++)
printf("%d ", a[i][j]);
for(i=row2,j=col2-1; j>=col1; j--)
printf("%d ", a[i][j]);
for(j=col1,i=row2-1; i>row1; i--)
printf("%d ", a[i][j]);
}
这是适用于任何 m x n 矩阵的 Java 实现。 其中 rows = 行数 和 Column = 列数
public static void printSpiral(int rows, int columns, int a[][])
{
int i, k = 0, l = 0;
/* k - starting row index
l - starting column index
*/
while (k < rows && l < columns)
{
/* Print the first row from the remaining rows */
for (i = l; i < columns; ++i)
{
System.out.println(a[k][i]);
}
k++;
/* Print the last column from the remaining columns */
for (i = k; i < rows; ++i)
{
System.out.println(a[i][columns-1]);
}
columns--;
/* Print the last row from the remaining rows */
if ( k < rows)
{
for (i = columns-1; i >= l; --i)
{
System.out.println(a[rows-1][i]);
}
rows--;
}
/* Print the first column from the remaining columns */
if (l < columns)
{
for (i = rows-1; i >= k; --i)
{
System.out.println(a[i][l]);
}
l++;
}
}
}
使用C#编写的工作代码,附带相关测试用例。它适用于任何 n x m
矩阵。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MatrixSpiralPrint
{
class Matrix
{
int[,] mat;
public Matrix(int[,] matrix)
{
mat = matrix;
}
void printHelper(int x)
{
Console.Write(string.Format("{0} ", x));
}
// print the top right of the matrix and
// recursively call the print bottom left on the submatrix.
void printTopRight(int colStart, int rowStart, int colEnd, int rowEnd)
{
int i = 0, j = 0;
// print Top row.
for (i = colStart; i <= colEnd; i++)
{
printHelper(mat[rowStart, i]);
}
// print Right column.
for (j = rowStart + 1; j <= rowEnd; j++)
{
printHelper(mat[j, colEnd]);
}
// Recursion base case: see if more layers need to be printed.
if (colEnd - colStart > 0 && rowStart!=rowEnd)
{
// print the bottom left of the sub matrix.
printBottomLeft(colStart, rowStart + 1, colEnd - 1, rowEnd);
}
}
// print the bottom left peel of the matrix and
// recursively call the print top right on the submatrix.
void printBottomLeft(int colStart, int rowStart, int colEnd, int rowEnd)
{
int i = 0, j = 0;
// print Bottom row in reverse order.
for (i = colEnd; i >= colStart; i--)
{
printHelper(mat[rowEnd, i]);
}
// print Left column in reverse order.
for (j = rowEnd - 1; j >= rowStart; j--)
{
printHelper(mat[j, colStart]);
}
// Recursion base case: see if more layers need to be printed.
if (colEnd - colStart > 0)
{
// print the top right of the sub matrix.
printTopRight(colStart + 1, rowStart, colEnd, rowEnd - 1);
}
}
void printMatrix()
{
int rowLength = mat.GetLength(0);
int colLength = mat.GetLength(1);
Console.WriteLine("Test Case");
for (int i = 0; i < rowLength; i++)
{
for (int j = 0; j < colLength; j++)
{
Console.Write(string.Format("{0} ", mat[i, j]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
}
public void printSpiral()
{
var maxRowIndex = mat.GetUpperBound(0);
var maxColIndex = mat.GetUpperBound(1);
printMatrix();
Console.WriteLine("Spiral Print");
printTopRight(0, 0, maxColIndex, maxRowIndex);
Console.WriteLine("\n---------------------------------");
}
}
class Program
{
static void Main(string[] args)
{
var matrix = new int[,] {
{ 1,2,3,4,5},
{ 6,7,8,9,10},
{ 11,12,13,14,15},
{ 16,17,18,19,20},
{ 21,22,23,24,25}
};
var mat = new Matrix(matrix);
mat.printSpiral();
matrix = new int[,] {
{ 1,2,3,4},
{ 5,6,7,8},
{ 9,10,11,12}
};
mat = new Matrix(matrix);
mat.printSpiral();
matrix = new int[,] {
{ 1,2,3},
{ 4,5,6},
{ 7,8,9},
{ 10,11,12},
};
mat = new Matrix(matrix);
mat.printSpiral();
matrix = new int[,] {
{ 1,2 }
};
mat = new Matrix(matrix);
mat.printSpiral();
matrix = new int[,] {
{ 1},
{ 2}
};
mat = new Matrix(matrix);
mat.printSpiral();
}
}
}
n x m
矩阵。该代码使用 @codaddict 在已接受的答案中发布的代码移植到 C#。我已更正了递归基本情况。