螺旋矩阵编程实现

42 篇文章 3 订阅
26 篇文章 2 订阅

今天看到google的一道面试题为

输出如下的矩阵(输入为方阵的行数N)

A[]=

1       16      15      14      13

2       17      24      23      12

3       18      25      22      11

4       19      20      21      10

5       6        7        8        9


也不知道怎么个叫法, 暂且叫它螺旋矩阵吧.


瞎想了两种实现方法,胡乱写的,明天再看看别人怎么做的罢:

一, 以下图的方式,从(0,0)元素开始,逆时针计算,这里每计算N-1次就转个方向, 连续四次后,剩下就是一个(N-2)*(N-2)的矩阵, 可以递归处理,

A[]=


1       16      15      14      13

2       17      24      23      12

3       18      25      22      11

4       19      20      21      10

5       6       7       8       9  


二. 另外一种方法是先找一个(N+1)*(N+1)的全0矩阵tempA,把这个矩阵的四周的元素都赋值1(非零),如:(N=5)

tempA[]=
1       1       1       1       1       1       1
1      
0       0       0       0       0       1
1      
0       0       0       0       0       1
1    
  0       0       0       0       0       1
1  
    0       0       0       0       0       1
1      
0       0       0       0       0       1
1       1       1       1       1       1       1

然后从(1,1)元素开始,逆时针填入1-25,有点像沿着墙壁走,非零的值就是墙壁,一旦碰壁就向左转.

最后变成

tempA[]=
1       1        1        1        1        1        1
1       1       16      15      14      13      1
1       2       17      24      23      12      1
1       3       18      25      22      11      1
1       4       19      20      21      10      1
1       5        6        7        8        9       1
1       1        1        1        1        1       1

然后把temp中的A部分取出来

A[]=

1       16      15      14      13

2       17      24      23      12

3       18      25      22      11

4       19      20      21      10

5       6       7       8       9


实现代码如下:

#include<stdio.h>

#include<malloc.h>
#include<string.h>
#include<stdlib.h>


#define down 	1
#define right 	2
#define up		3
#define left	4

void spiral_matrix(int *A, int N)
{
	int *tempA;
	int i=0,j=0;
	int direction = down;
	int col=1,row=1;

	if(A == NULL)exit(1);
	if(N<=0)exit(1);

	tempA =(int *)malloc(sizeof(int)*(N+2)*(N+2));
	memset(tempA,0, sizeof(int)*(2+N)*(2+N));

	for(i = 0; i < N+2; i++)
	{
		tempA[i]=1;
		tempA[i*(2+N)]=1;
		tempA[i*(2+N)+N+1]=1;
		tempA[(N+1)*(2+N)+i]=1;
	}
	printf("tempA[]=\n");
	for(i=0;i<N+2;i++)
	{
			for(j=0;j<N+2;j++)
			{
					printf("%d\t",tempA[i*(N+2)+j]);
			}
			printf("\n\n");
	}

	printf("\n");
	printf("\n");
//	printf("\n");
	for(i=1;i<N*N;i++)
	{
		switch(direction)
		{
			case down:
				if(tempA[(col+1)*(N+2) +row] == 0)
				{
					tempA[col*(N+2)+row] = i;
					col++;
				}
				else
				{
					tempA[col*(N+2)+row] = i;
					direction = right;
					row++;
				}
				break;
			case right:
				if(tempA[col*(N+2) +(row+1)] == 0)
				{
						tempA[col*(N+2)+row]=i;
						row++;
				}
				else
				{
					tempA[col*(N+2)+row] = i;
					direction = up;
					col--;
				}
				break;
			case up:
				if(tempA[(col-1)*(N+2)+row] == 0)
				{
						tempA[col*(N+2)+row] =i;
						col--;
				}
				else
				{
					tempA[col*(N+2)+row] = i;
						direction = left;
						row--;
				}
				break;
			case left:
				if(tempA[col*(N+2)+row-1] == 0)
				{
						tempA[col*(N+2)+row] = i;
						row--;
				}
				else
				{
					tempA[col*(N+2)+row] = i;
						direction = down;
						col++;
				}
				break;
			default:
				printf("direction error!\n");
		}
	}
	
	tempA[col*(N+2)+row] = i;
	printf("tempA[]=\n\n");
	for(i=0;i<N+2;i++)
	{
		for(j=0;j<N+2;j++)
			printf("%d\t",tempA[i*(N+2)+j]);
		printf("\n");
	}
	
	for(i=0;i<N;i++)
			for(j=0;j<N;j++)
					A[i*N+j]=tempA[(i+1)*(N+2)+j+1];

}


int main()
{
	int *A;
	int N;
	int i,j,k;
	printf("N=");
	scanf("%d",&N);
	printf("\n");

	if(N<=0)exit(1);
	A = (int *)malloc(sizeof(int)*N*N);

	memset(A,0,sizeof(int)*N*N);

	spiral_matrix(A,N);
	printf("\n\n");
	printf("A[]=\n\n");
	for(i=0;i<N;i++)
	{
			for(j=0;j<N;j++)
					printf("%d\t",A[i*N+j]);
			printf("\n\n");
	}
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值