摘要

本文主要讲解三种螺旋队列的实现方式和打印输出:

  • 从中心往外端顺时针旋转,记为『外螺旋队列』
  • 从左顶点开始,绕剩下的最大圈顺时针往内旋转,记为『内螺旋队列』
  • 从左顶点开始,之字形旋转(只能同行同列地移动),记为『 』螺旋队列』
  • 从左顶点开始,之字形旋转(只能沿-45°斜线移动),记为 『/ 螺旋队列 』

前三个螺旋队列图示如下:

1. 外螺旋队列

通过几个标记位,来确定其他值的大小,

由这两个值再来确定其他值,首先,我们可以确定这个值的大致范围: maxAbs=max{ fabs(r),fabs(c)},这样这个值就在 (2maxAbs-1)2~(2maxAbs+1)2的范围。接下来,我们从东南西北四个方向分析具体的值:

令$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}

  • 北:$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. 输出

最后,给出动态分配二维数组和打印程序,主程序与最后的结果。

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;
}

      

[interview]螺旋队列问题的更多相关文章

  1. 螺旋队列和hiho1525逃离迷宫3

    我是真调不出错误了! hiho1525逃离迷宫3 #include <stdio.h> #include <stdlib.h> #include <math.h> ...

  2. 螺旋队列(p98)

    先判断这个坐标代表的数位于哪一层,然后依据该层最大的数去计算这个坐标所代表的数. #include"iostream" #include"stdio.h" #i ...

  3. 语言总结—C/C++

    参考<程序员面试宝典> 1. 基本概念 1.1 赋值语句 例1. 按位与操作,例如:a=3,b=3,a&b值等于 0011 & 0011 结果还是0011,那么值还是3: ...

  4. 20140331 HOG代码调试 Boost库安装

    1.CUDAHOG代码调试 错误1: 错误提示:(main.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall cudaHOG::cudaH ...

  5. 《Cracking the Coding Interview》——第3章:栈和队列——题目7

    2014-03-19 03:20 题目:实现一个包含阿猫阿狗的先入先出队列,我要猫就给我一只来的最早的猫,要狗就给我一只来的最早的狗,随便要就给我一只来的最早的宠物.建议用链表实现. 解法:单链表可以 ...

  6. 《Cracking the Coding Interview》——第3章:栈和队列——题目5

    2014-03-18 05:33 题目:用两个栈来实现一个队列. 解法:栈是反的,队列是正的,反了再反就正过来了.所以,请看代码.操作中时间复杂度有O(1)的,有O(n)的,但均摊下来时间符合O(1) ...

  7. 《Cracking the Coding Interview》——第3章:栈和队列——题目6

    2014-03-19 03:01 题目:给定一个栈,设计一个算法,在只使用栈操作的情况下将其排序.你可以额外用一个栈.排序完成后,最大元素在栈顶. 解法:我在草稿纸上试了试{1,4,2,3}之类的小例 ...

  8. 《Cracking the Coding Interview》——第3章:栈和队列——题目4

    2014-03-18 05:28 题目:你肯定听过汉诺威塔的故事:三个柱子和N个从小到大的盘子.既然每次你只能移动放在顶上的盘子,这不就是栈操作吗?所以,请用三个栈来模拟N级汉诺威塔的玩法.放心,N不 ...

  9. 《Cracking the Coding Interview》——第3章:栈和队列——题目3

    2014-03-18 05:17 题目:设计一个栈,这个栈实际上由一列子栈组成.每当一个子栈的大小达到n,就新产生下一个子栈.整个栈群对外看起来就像普通栈一样,支持取顶top().压入push().弹 ...

随机推荐

  1. windows下,python3安装django和mysql驱动

    1.安装python3和django (1)Python 下载地址:https://www.python.org/downloads/ (2)Django 下载地址:https://www.djang ...

  2. python 类和对象的属性

    python类和对象的属性分为类属性和对象属性两大类,类属性属于类,而对象属性属于对象. 1. 父类的对象属性会被子类的对象继承. 2. 父类的类属性会被子类继承,还是作为类属性,如果父类改变了类属性 ...

  3. GEO--工具 ScanGEO

    http://scangeo.dartmouth.edu/ScanGEO/ ScanGEO - parallel mining of high-throughput gene expression d ...

  4. Linux Shell参数替换

    Linux Shell参数替换 2013-06-03 10:01 by 轩脉刃, 1816 阅读, 0 评论, 收藏, 编辑 Bash中的符号的作用是参数替换,将参数名替换为参数所代表的值.对于 来说 ...

  5. vector的坑——C++primer练习6.33总结

    说来惭愧,一道简单的对vector递归的题目写了一个多小时,最后还是请教了大神才改出来. 首先贴上原代码: void return_vector(vector<int>::iterator ...

  6. Java 最常见的 200+ 面试题:面试必备

    这份面试题,包含的内容了十九了模块:Java 基础.容器.多线程.反射.对象拷贝.Java Web 模块.异常.网络.设计模式.Spring/Spring MVC.Spring Boot/Spring ...

  7. 【Python】模块学习之Timer定时任务,递归定时自调获取博客浏览量

    Timer定时任务 下面是Timer函数的官方doc介绍信息 """ Call a function after a specified number of second ...

  8. 【Python】模块学习之使用paramiko连接Linux,远程执行命令,上传下载、文件

    本文主要介绍paramiko远程执行linux命令,及在服务器上进行文件的上传.下载 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. ...

  9. 初学Selenium遇到的那些坑

    一.遇到一个下拉选择框,可以点击继续选择: 所以click两次就可以了: 二.国际话问题 bdId.selectByIndex(index);//index位下拉框内容的下标,从0开始,  数组形式[ ...

  10. Postman的安装

    打开chrome->设置->扩展程序->获取更多扩张程序:输入 postman就可以安装了    可能需要蓝灯FQ 安装好了直接打开即可使用