将二维数组旋转 90 度
我正在研究这段关于旋转 NxN 矩阵的代码;我已经跟踪了该程序无数次,并且我有点了解实际轮换是如何发生的。它基本上首先旋转角,然后按顺时针方向旋转角之后的元素。我只是不明白几行代码,可以这么说,代码仍然没有在我的大脑中“驱动回家”。请帮忙。我将其旋转 90 度,以 4x4 矩阵作为我的追踪示例。
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
变成
[3][9][5][1]
[4][0][6][2]
[5][1][7][3]
[6][2][8][4]
public static void rotate(int[][] matrix, int n){
for(int layer=0; layer < n/2; ++layer) {
int first=layer; //It moves from the outside in.
int last=n-1-layer; //<--This I do not understand
for(int i=first; i<last;++i){
int offset=i-first; //<--A bit confusing for me
//save the top left of the matrix
int top = matrix[first][i];
//shift left to top;
matrix[first][i]=matrix[last-offset][first];
/*I understand that it needs
last-offset so that it will go up the column in the matrix,
and first signifies it's in the first column*/
//shift bottom to left
matrix[last-offset][first]=matrix[last][last-offset];
/*I understand that it needs
last-offset so that the number decreases and it may go up the column (first
last-offset) and left (latter). */
//shift right to bottom
matrix[last][last-offset]=matrix[i][last];
/*I understand that it i so that in the next iteration, it moves down
the column*/
//rightmost top corner
matrix[i][last]=top;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果你画一个图表,就更容易理解这样的算法,所以我在 Paint 中制作了一张快速图片来演示 5x5 矩阵:D
外部
for(int layer=0; layer < n/2; + +layer)
循环从外到内迭代各层。外层(第 0 层)由彩色元素表示。每层实际上都是需要旋转的元素的正方形。对于 n = 5,层 将采用 0 到 1 之间的值,因为有 2 层,因为我们可以忽略不受旋转影响的中心元素/层。 first 和 last 指的是图层中元素的第一行和最后一行/列;例如,第 0 层包含从行/列 first = 0 到 last = 4 的元素,第 1 层包含从行/列 1 到 3 的元素。然后对于每个层/方块,内部for(int i=first; i偏移表示我们沿着正方形边的距离。对于下面的 5x5,我们首先旋转红色元素(偏移 = 0),然后旋转黄色(偏移 = 1),然后旋转绿色和蓝色。箭头 1-5 演示了红色元素的 4 元素旋转,以及以相同方式执行的其余元素的 6+ 旋转。请注意 4 元素旋转本质上是 5 分配循环交换,其中第一个分配暂时搁置一个元素。此分配的
//save the top left of the Matrix
注释具有误导性,因为矩阵 [first][i] 不一定是矩阵的左上角,甚至不一定是该层。另请注意,正在旋转的元素的行/列索引有时与偏移成正比,有时与其倒数最后 - 偏移成正比。我们以这种方式沿着外层的侧面移动(由first = 0和last = 4划分),然后移动到内层(first = 1和last = 3)并在那里做同样的事情。最终,我们到达了中心,就完成了。
It's easier to understand an algorithm like this if you draw a diagram, so I made a quick pic in Paint to demonstrate for a 5x5 matrix :D
The outer
for(int layer=0; layer < n/2; ++layer)
loop iterates over the layers from outside to inside. The outer layer (layer 0) is depicted by coloured elements. Each layer is effectively a square of elements requiring rotation. For n = 5, layer will take on values from 0 to 1 as there are 2 layers since we can ignore the centre element/layer which is unaffected by rotation. first and last refer to the first and last rows/columns of elements for a layer; e.g. layer 0 has elements from Row/Column first = 0 to last = 4 and layer 1 from Row/Column 1 to 3.Then for each layer/square, the inner
for(int i=first; i<last;++i)
loop rotates it by rotating 4 elements in each iteration. Offset represents how far along the sides of the square we are. For our 5x5 below, we first rotate the red elements (offset = 0), then yellow (offset = 1), then green and blue. Arrows 1-5 demonstrate the 4-element rotation for the red elements, and 6+ for the rest which are performed in the same fashion. Note how the 4-element rotation is essentially a 5-assignment circular swap with the first assignment temporarily putting aside an element. The//save the top left of the matrix
comment for this assignment is misleading since matrix[first][i] isn't necessarily the top left of the matrix or even the layer for that matter. Also, note that the row/column indexes of elements being rotated are sometimes proportional to offset and sometimes proportional to its inverse, last - offset.We move along the sides of the outer layer (delineated by first=0 and last=4) in this manner, then move onto the inner layer (first = 1 and last = 3) and do the same thing there. Eventually, we hit the centre and we're done.
这触发了WTF。原地旋转矩阵的最简单方法是
然后将 是列主的,第二个操作是交换列,因此具有良好的数据局部性属性。如果矩阵是行主矩阵,则首先排列行,然后转置。
This trigger a WTF. The easiest way to rotate a matrix in place is by
When matrices are column-major, the second operation is swapping columns, and hence has good data locality properties. If the matrix is row major, then first permute rows, and then transpose.
这是解决此问题的递归方法:
// 将 2 D 数组 (mXn) 旋转 90 度
Here is a recursive way of solving this:
// rotating a 2 D array (mXn) by 90 degrees