摘要

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

  • 从中心往外端顺时针旋转,记为『外螺旋队列』
  • 从左顶点开始,绕剩下的最大圈顺时针往内旋转,记为『内螺旋队列』
  • 从左顶点开始,之字形旋转(只能同行同列地移动),记为『 』螺旋队列』
  • 从左顶点开始,之字形旋转(只能沿-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. Zoom Me FAQ

    Q: How to config custom shortcuts? A: Enter the preferences setting window from menu bar "Prefe ...

  2. LeetCode——Longest Palindromic Subsequence

    1. Question Given a string s, find the longest palindromic subsequence's length in s. You may assume ...

  3. Numpy 数据分析基础

    numpy 库 ndarray : numpy 的关键 a = np.array([1,2,3]) # 轴 a.ndim # 数组长度 a.size # 数组的型 a.shape # 类型 a.dty ...

  4. MySQL Order By Rand()效率分析

    最近研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() L ...

  5. web微信开发总结

    这两天使用Django开发了web微信,实现了显示联系人以及收发消息的功能. 总结下这过程中使用到的一些知识. 1 http请求 通过chrome浏览器自带的开发者工具查看每次请求的信息,分析请求,包 ...

  6. 解决silk-v3-decoder-master转换wav时,百度语音解析问题

    $cur_dir/silk/decoder >& if [ ! -f "$1.pcm" ]; then /usr/local/ffmpeg/bin/ffmpeg -y ...

  7. "".indexOf() "",replace(",","")的应用

    自动化校验时,可能有些时候需要校验生成的值,如销售机会编号,每次生成时都是不一样的:所以我们需要提取出他们 assertTrue("SL17-001100".indexOf(dri ...

  8. HDU - 59562016ACM/ICPC亚洲区沈阳站I - The Elder 树上斜率优化dp

    题意:给定上一棵树,然后每条边有一个权值,然后每个点到 1 的距离有两种,第一种是直接回到1,花费是 dist(1, i)^2,还有另一种是先到另一个点 j,然后两从 j 向1走,当然 j 也可以再向 ...

  9. hihocoder1457

    http://hihocoder.com/problemset/problem/1457 找不重复子串的和 topo序搞一搞,用父亲更新儿子节点的val,记得乘上节点数 //#pragma comme ...

  10. python2.7安装requests

    我这里的是linux CentOS7版本 直接执行命令pip install requests 安装即可,如果提示没有pip这个命令要先安装pip 安装步骤如下: 1. 首先检查Linux有没有安装P ...