数字螺旋输出,O(1)空间复杂度解法

问题定义:
输入n,将数字1...n螺旋输出。
举例:
n=2,输出结果为
1 2
4 3

n=3,输出结果为
1 2 3
8 9 4
7 6 5

解题:
此题解法很多,常见的多要借助二维数组来存储待输出的结果,空间复杂度为O(n*n)
这里介绍一个不借助二维数组的方法,将空间法复杂度降为O(1)。
引入层的概念,用 l 表示,如:
1 2 3
8 9 4
7 6 5 有2层,1、2、3、4、5、6、7、8是第0层(从0计数),9是第1层。

n*n矩阵所含层数 L = ceil(n/2), 取上限。如3*3矩阵有2层,4*4矩阵有2层, 5*5矩阵有3层。
每一层都是一个矩形,有4条边(只有一个数组成的层,看成矩形点),如:
1 2 3
8 4
7 6 5 
矩形大小 s 用边长度来定义,如上面矩形,其大小为3(边包含3个元素)。

算法关键处:找到二维矩阵下标值 i,j 与 l,n的关系,进而找到每一个ij位置所放的数与l,n的关系。
对于二维矩阵中任一位置A[i,j], A[i,j]所处的层 l = min(i, n-j-1) (i<=j) or l = min(j, n-i-1) (i>j)

第 l 层的矩形大小 s = n-2*l
第 l 层包含的元素个数为 (n-2*l-1)*4
第 l 层之外的所有层包含的元素个数为(0 至 l-1层):sw = 4*l*(n-l)

A[i,j]位置应放置的数为:
//A[i,j]位置出于矩形的上边
if(i=l && i<=j) A[i,j] = sw + j-l+1
//A[i,j]位置出于矩形的右边
if(j=n-1-l && i<=j) A[i,j] = sw + s + i-l
//A[i,j]位置出于矩形的下边
if(i=n-1-l && i>=j) A[i,j] = sw + 2*s -1 + n-1-l-j
//A[i,j]位置出于矩形的左边
if(j=l && i>=j) A[i,j] = sw + 3*s-2 + n-1-l-i

实现代码如下:

int main()
{
int n,l;
scanf("%d", &n);

int i,j,value;
for(i=0; i=j) { value = sw + 2*(n-2*l)-1 + n-1-l-j;}
else if(j==l && i>=j) { value = sw + 3*(n-2*l)-2 + n-1-l-i; }
else value = -1;

printf("%5d", value);
}
printf("\n");
}

system("pause");
return 0;
}


另一种解法: 空间复杂度为O(N*N) 时间复杂度O(n*n)

模拟行走过程(或迷宫走法),四个方向(→↓←↑)循环变换。

int main()
{
int a[N][N] = {0};

int n;
scanf("%d", &n);

int di=0, dj=1;
int i=0, j=-1;
int count = 1;
while(count<=n*n)
{
if(i+di >= 0 && i+di < n && j+dj >= 0 && j+dj < n && a[i+di][j+dj] == 0) a[i+=di][j+=dj] = count++;
else if(di==0 && dj==1) di=1, dj=0;
else if(di==1 && dj==0) di=0, dj=-1;
else if(di==0 && dj==-1) di=-1, dj=0;
else if(di==-1 && dj==0) di=0, dj=1;
}

for(i=0; i




你可能感兴趣的:(算法)