[interview]螺旋隊列問題

摘要

本文主要講解三種螺旋隊列的實現方式和打印輸出:數組

  • 從中心往外端順時針旋轉,記爲『外螺旋隊列』
  • 從左頂點開始,繞剩下的最大圈順時針往內旋轉,記爲『內螺旋隊列』
  • 從左頂點開始,之字形旋轉(只能同行同列地移動),記爲『 』螺旋隊列』
  • 從左頂點開始,之字形旋轉(只能沿-45°斜線移動),記爲 『/ 螺旋隊列 』

前三個螺旋隊列圖示以下:spa

1. 外螺旋隊列

經過幾個標記位,來肯定其餘值的大小,3d

由這兩個值再來肯定其餘值,首先,咱們能夠肯定這個值的大體範圍: maxAbs=max{ fabs(r),fabs(c)},這樣這個值就在 (2maxAbs-1)2~(2maxAbs+1)2的範圍。接下來,咱們從東南西北四個方向分析具體的值:blog

令$N=maxAbs$, 標誌位上平方數元素的表示爲:隊列

\begin{gather}
f(-k,k) = (2k+1)^2 , \qquad k=0,1,2...\\
f(k,-(k-1)) = (2k)^2, \qquad k=1,2...
\end{gather}class

  • 北:$f(r,c)=f(-N,N)-(N-c), \qquad r=-N,r<c$
  • 東:$f(r,c)=f(-(N-1),(N-1))+(r+(N-1))+1, \qquad c=N,r>-c$
  • 南:$f(r,c)=f(N,-(N-1))-(c+(N-1)), \qquad r=N,r>c$
  • 西:$f(r,c)=f(N,-(N-1))+(N-r)+1, \qquad c=-N,r<-c$
int rotQueue1(int r,int c)
{
	if(r>0 && r+c==1)
		return (2*r)*(2*r);
	if(r<=0 && r+c==0)
		return (2*c+1)*(2*c+1);
	int N=fabs(r)>fabs(c)?fabs(r):fabs(c);
	if( r==-N && r<c)
		return rotQueue1(-N,N)-(N-c);
	else if( c==N && r>-c)
		return rotQueue1(-(N-1),(N-1))+(r+(N-1))+1;
	else if( r==N && r>c )
		return rotQueue1(N,-(N-1))-(c+(N-1));
	else if( c==-N && r<-c)
		return rotQueue1(N,-(N-1))+(N-r)+1;
}

2. 內螺旋隊列

能夠經過迭代創建數組,外圈循環從 i←0 to n/2,表示從外到內,循環圈子慢慢縮小,內圈循環從按照北東南西的順序遞增地創建數組。循環

int **rotQueue2(int r,int c)
{
	int **a=malloc2D(r,c);
	int m=1;
	for(int i=0; i<r/2; i++)
	{
		for(int j=i;j<c-1-i;j++)
			a[i][j] = m++;
		for(int j=i;j<r-1-i;j++)
			a[j][c-1-i] = m++;
		for(int j=c-1-i;j>i;j--)
			a[r-1-i][j] = m++;
		for(int j=r-1-i;j>i;j--)
			a[j][i] = m++;
	}
	if(r%2==1&&c%2==1)
		a[r/2][c/2]=m;
	return a;
}

3. 』螺旋隊列

有兩個方法肯定數組:程序

  1. 可用標誌位——平方數的加減獲得,行列標從1開始的話, a(2k,1)=(2k)2 , a(1,2k-1)=(2k-1)2 相似於rotQueue1
  2. 相似於內螺旋隊列,總體迭代賦值創建數組,下面用第二種。
int **rotQueue3(int N)
{
	int **a=malloc2D(N,N);
	int m=1;
	a[0][0]=m++;
	for(int i=1;i<N; ++i ){
		if(i%2==1){
			for(int j=0;j<=i;++j)// j爲行
				a[j][i]=m++;
			for(int j=i-1;j>=0;--j)// j爲列
				a[i][j]=m++;
		}
		else{
			for(int j=0;j<=i;++j)// j爲列
				a[i][j]=m++;
			for(int j=i-1;j>=0;--j)// j爲行
				a[j][i]=m++;
		}
	}
	return a;
}

4. / 螺旋隊列 (zigzag數組)

能夠將這個數組當作一個上三角形和一個倒三角形的組合。分紅兩部分賦值便可。(分析略去)。方法

 

5. 輸出

最後,給出動態分配二維數組和打印程序,主程序與最後的結果。im

int** malloc2D(int r,int c)
{
	int **pt2D =(int**) malloc( r*sizeof(int*) );
	for(int i=0; i< r;i++){
		pt2D[i] = (int*)malloc( c*sizeof(int) );
		for(int j=0;j<c;j++)
			pt2D[i][j]=0;
	}
	return pt2D;
}

void printRotQueue(int**a,int r,int c)
{
	for(int i=0; i<r;i++){
		for(int j=0;j<c;j++){
			printf("%3d ",a[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	int r=5,c=5;
	printf("rotQueue1(%d,%d):\n",r,r);
	for(int i= -r/2; i<=r/2 ; ++i ){
		for(int j= -r/2;j<=r/2;++j){
			printf("%3d ",rotQueue1(i,j) );
		}
		printf("\n");
	}

	int** a2=rotQueue2(r,c);
	printf("\nrotQueue2(%d,%d):\n",r,c);
	printRotQueue(a2,r,c);
	printf("\nrotQueue3(%d,%d):\n",r,r);
	int** a3=rotQueue3(r);
	printRotQueue(a3,r,r);
	return 0;
}

      

相關文章
相關標籤/搜索