【问题标题】:Cracking the Coding Interview, 6th edition, 1.7破解编码面试,第 6 版,1.7
【发布时间】:2019-07-21 12:52:33
【问题描述】:

给定一个由 nxn 矩阵表示的图像,其中图像中的每个像素为 4 个字节,编写一个将图像旋转 90 度的方法。 (到位)

我做了低效的解决方案,将每一行复制到一个临时然后执行交换,占用 o(N) 空间,下面的实际解决方案更好,但我不明白。

def rotate_matrix(matrix):
    '''rotates a matrix 90 degrees clockwise'''
    n = len(matrix)
    for layer in range(n // 2):
        first, last = layer, n - layer - 1
        for i in range(first, last):
            # save top
            top = matrix[layer][i]

            # left -> top
            matrix[layer][i] = matrix[-i - 1][layer]

            # bottom -> left
            matrix[-i - 1][layer] = matrix[-layer - 1][-i - 1]

            # right -> bottom
            matrix[-layer - 1][-i - 1] = matrix[i][- layer - 1]

            # top -> right
            matrix[i][- layer - 1] = top
    return matrix

以上代码是Python解决方案,

我不明白 for 循环,为什么它在 n//2 范围内,从 first 到 n-layer-1。

另外,为什么这个问题提到了这4个字节似乎是无用的信息。

谢谢!

【问题讨论】:

  • 在 python 4 bytes 中并不重要,但在其他语言中,您可能必须知道要保留多大的数组才能复制值。
  • 它使用n // 2,因为它替换了大小为(n // 2, n // 2)的正方形中的像素,

标签: python arrays python-3.x matrix rotation


【解决方案1】:

重要的是要考虑n 是奇数还是偶数,因为必须以不同的方式来处理问题。不过,在这两种情况下,正方形都可以细分为多个象限。

n是奇数:

正方形被分成四个矩形象限。在双 for 循环的每次迭代中,恰好旋转了 4 个元素,每个象限一个。中间元素永远不会被访问,因为它在循环中保持在中间。

+-------+---+ 
| x   x | x | 
+---+---+   | 
| x | x | x | 
|   +---+---+ 
| x | x   x | 
+---+-------+

n 是偶数:

矩阵分为 4 个正方形象限。同样,在双 for 循环的每次迭代中,恰好旋转了 4 个元素,每个象限一个。 在偶数情况下,每个元素都必须移动(即没有完美的中心元素)。

+-------+-------+
| x   x | x   x |
|       |       |
| x   x | x   x |
+-------+-------+
| x   x | x   x |
|       |       |
| x   x | x   x |
+-------+-------+

n // 2n - layer - 1 只是伪装的地板和天花板功能。 n 是奇数,需要地板和天花板。这些值用于在其中一个象限上设置迭代。然后,无论一个象限中存在多少元素,都会发生 4 次交换(在 top 临时值的帮助下)。

【讨论】:

    【解决方案2】:

    基本上,我们通过从矩阵的外边界到内核旋转元素,顺时针交换项目。

    我们以下面的矩阵为例:

    1  2  3  4
    5  6  7  8
    9  10 11 12
    13 14 15 16
    

    在第一次迭代中,我们关注的是外部元素:

    1  2  3  4
    5  x  x  8
    9  x  x  12
    13 14 15 16
    

    我们开始(内循环)顺时针交换所有元素。在我们的示例中,我们将 4(将其存储在临时变量中之后)替换为 1。之后,我们将 1 替换为 13,依此类推。最后我们用我们保存的 4 替换 16。我们继续这样做,直到所有元素都被交换。所以在外循环的第一次迭代之后,我们的数组看起来像这样:

    13  9  5 1
    14  6  7 2 
    15 10 11 3
    16 12  8 4
    

    之后,我们移动到下一层。在我们的例子中,我们现在来看看:

    x  x  x x
    x  6  7 x 
    x 10 11 x
    x x  x  x
    

    我们再次一一交换所有元素,如上所示。我们有第 n/2 次迭代,因为对于不均匀的 n,最后一次迭代给我们留下了一个元素,显然不需要旋转。

    这给我们留下了:

    13  9 5 1
    14 10 6 2 
    15 11 7 3
    16 12 8 4
    

    像 c 这样的语言需要 4 个字节,我们必须手动管理内存。它们的起源很可能是每个像素由 3 种颜色(红色、绿色和蓝色)组成,每种颜色由 8 位 (0-255) 表示。此外,不透明度可能还有另外 8 位。所以我们剩下 32 位 = 4 字节。

    【讨论】:

      猜你喜欢
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2017-08-31
      • 2012-09-24
      • 2018-11-21
      • 2012-11-04
      • 2013-09-05
      相关资源
      最近更新 更多