如何在一维数组中执行螺旋顺序遍历?

时间:2013-01-11 19:13:36

标签: algorithm data-structures

  

可能重复:
  Looping in a spiral
  Writing a string in a spiral
  Print two-dimensional array in spiral order
  2d Array in Spiral Order

我们有一个矩阵

形式的数据
0 0 0 0 0
0 1 2 3 0
0 4 5 6 0
0 7 8 9 0
0 0 0 0 0

以这种方式存储在1d数组中

[0 0 0 0 0 0 1 2 3 0 0 4 5 6 0 0 7 8 9 0 0 0 0 0 0]

这是一个零填充的3x3阵列转换为5x5。我们知道起始索引和结束索引。

正如我们所看到的,我们可以执行25次操作并打印所有值,但是如果我们按螺旋顺序排列,我们理想情况下应该只执行9次操作。

有谁知道怎么做?

我们知道行数和列数。这里是行= 5 cols = 5.

因此,起始索引将是行+ 1,而结束索引将是行* cols-6

我将其视为螺旋顺序遍历。

2 个答案:

答案 0 :(得分:0)

假设您的5x5矩阵假设零指数基数,您知道行索引是:
0,1,2,3,4
5,6,7,8,9
10,11,12,13,14
15,16,17,18,19
20,21,22,23,24

您知道您的第一个索引是6,而最后一个索引是18。因此,作为一个起点,您知道可以消除矩阵的以下部分:

0,1,2,3,4

19,20,21,22,23,24,25

这算作2次操作。

你也知道,既然你是从索引6开始而且它是3x3,你只需要去索引8,这是一个操作。

然后,您需要将5添加到之前的6索引中,这会产生11并再次继续(总计2次操作)当前操作计数为{{1 }})

使用5再次执行此操作,即可获得11个操作。再获得2项操作,最终得到16。现在共有8个操作。

答案 1 :(得分:0)

我会做这样的事情:

   POINT ul = (start_idx/width, start_idx%width);
   POINT br = (end_idx/width, end_idx%width);
   POINT p = ul
   dir = RIGHT;
   while (ul != br)
     visit(ARRAY[p.x+p.y*WIDTH])
     case dir
        when RIGHT:   
           p.x+=1
           if (p.x==br.x) 
             dir = DOWN
             ul.y++;
         when DOWN
           p.y+=1
           if (p.y==br.y) 
             dir = LEFT
             br.x--;
         when LEFT: 
            //like RIGHT but -1 and adjust br.y upwards when done
         when UP:
            //like DOWN but -1 and adjust ul.x rightward when done
    endwhile

想法是跟踪要访问的虚拟x和y。移动点以沿着由起点和终点定义的框的侧面进行访问。在完成访问时调整两侧。