程序员面试宝典——螺旋队列解法解析

由于网络问题,本页还有一些我自己画的说明图片没有贴上来,稍后会完善的。

另:对螺旋队列求解的举例说明和源代码放在下一篇文章《程序员面试宝典——螺旋队列解法解析2》中。

欢迎大家提出自己的见解,不明白的可以给我留言。

 

螺旋队列

面试例题:

程序员面试宝典——螺旋队列解法解析_第1张图片

        看清以上数字排列的规律,设1点的坐标为(0, 0),x方向向右为正,y方向向下为正。

        例如,7的坐标为(-1, -1),2的坐标为(0, 1),3的坐标为(1, 1)。

        编程实现输入任意一点坐标(x, y),输出所对应的数字。

 

我的分析:

       1.数字排列规律:以数字1为圆心,顺时针由里向外画圈,依次显示数字为1,2,3,4,5,6……,这就是所谓的螺旋队列。示意图如下:

程序员面试宝典——螺旋队列解法解析_第2张图片

       2.依照题目要求建立坐标轴,示意图如下:

程序员面试宝典——螺旋队列解法解析_第3张图片

       3.将螺旋队列从里到外画圈,依次编号为圈0,圈1,圈2……。

  • 特征1:圈0有1个数,值为1(12 );圈1最大值为9(32 );圈2最大值为25(52 )……
  • 特征2:圈0只有1个数,x=y=0;圈1中每个数的x、y坐标都满足  |x|<=1&&|y|=1   或者   |y|<=1&&|x|=1   ;圈2中每个数的x、y坐标都满足  |x|<=2&&|y|=2  或者  |y|<=2&&|x|=2。
  • 特征3:每个圈都是个四四方方的正方形,边长分别为0,2,4,6……。

那么想要根据x、y坐标求取数字值v

        首先要能根据x、y坐标确定当前所求数字在哪一圈。依据第2条特征,我们可知:x、y坐标绝对值的最大值即为当前所求数字所在的圈号,用 t 表示, t = max(|x| , |y|)

        依据第1条特征可知,(2t+1)2 即为圈 t 的最大值,那么圈 t-1 的最大值为多少呢?对的,是(2t-1)2 。也就是说圈 t 所有数字的取值范围我们可以用这个半开半闭区间表示:( (2t-1)2 , (2t+1)2 ]。

        那么圈 t 上的数字值v(x,y,t) = (2t-1)2 + 顺时针步长

        下面的问题就是如何求顺时针步长,我们需要分情况讨论。分类的标准参照特征2,可分为以下4类。我们这里定义一个变量u,记录当前圈(即正方形)的边长。依据特征3,虽然圈 t 的每边有 2t+1 个数字,但是其边长为2t。u = 2t ,从前一圈的最大值顺时针数步长。

        1) y = t 这一行

            顺时针步长 = u + u/2 - x;

        2) x = -t 这一列

            顺时针步长 = 2u + u/2 - y;

        3) y = -t 这一行

            顺时针步长 = 3u + u/2 + x;

        4) x = t 这一列

            顺时针步长 = u/2 + y;

        需要注意的是: x = t 这一列必须放在y = -t 这一行的后面求。这样做的原因是:坐标为(t,  -t)的数字是当前圈t的最大值,这个最大值与y = -t 这一行的数字形成等差,单位步长为1,所以通过y = -t 这一行的公式来求是可取的;但是用x = t 这一列的公式来求就不对了。为了保证该坐标的数字用y = -t 的公式来求,必须在条件语句中将y = -t 放在x = t 之前。

 

 

你可能感兴趣的:(编程,网络,面试)