二维矩阵旋转

假设我们有一个2x2的矩阵如下:

1 2
3 4

我们需要生成这个矩阵通过顺时针旋转90度、180度、270度以及360度(即原矩阵)的所有可能形态,并将每种形态转换为字符串。

首先,初始化dxdy数组,它们代表矩阵中每个元素的位置偏移量:

int dx[] = {0, 0, 1, 1}; // 行偏移
int dy[] = {0, 1, 1, 0}; // 列偏移

这些偏移量是针对原始矩阵的索引。在2x2矩阵中,我们可以通过这些偏移量直接访问所有元素:

  • (0,0)对应元素1
  • (0,1)对应元素2
  • (1,1)对应元素4
  • (1,0)对应元素3

模拟旋转过程

我们将通过四次循环来模拟每次旋转90度的情况,并产生一个字符串来代表矩阵在该旋转状态下的布局。

原矩阵(360度旋转或无旋转)

在不进行旋转的情况下,我们直接根据dxdy的顺序访问元素:

直接访问顺序:1 (0,0) -> 2 (0,1) -> 4 (1,1) -> 3 (1,0)

生成的字符串为:"1243"。

顺时针旋转90度

在顺时针旋转90度后,矩阵变为:

3 1
4 2

为了获取这个旋转状态下的字符串,我们需要重新考虑如何通过dxdy访问元素。旋转后的访问顺序变为:

访问顺序变为:3 (1,0) -> 1 (0,0) -> 2 (0,1) -> 4 (1,1)

生成的字符串为:"3124"。

顺时针旋转180度

再次旋转90度(总共180度),矩阵变为:

4 3
2 1

对应的访问顺序和生成的字符串为:

访问顺序变为:4 (1,1) -> 3 (1,0) -> 1 (0,0) -> 2 (0,1)

生成的字符串为:"4312"。

顺时针旋转270度

最后,将矩阵再旋转90度(总共270度),得到:

2 4
1 3

对应的访问顺序和生成的字符串为:

访问顺序变为:2 (0,1) -> 4 (1,1) -> 3 (1,0) -> 1 (0,0)

生成的字符串为:"2431"。

为什么是k = (i + j) % 4

这里的i表示当前旋转状态(0表示无旋转,1表示旋转90度,2表示旋转180度,3表示旋转270度),而j代表原矩阵中元素的索引。k则是计算出来的在旋转后矩阵中对应的新位置。

理解k = (i + j) % 4

这个公式背后的思想是利用模运算来循环访问矩阵中的元素位置。考虑一个2x2矩阵,其元素的索引可以表示为:

  • (0, 0) 第一个元素
  • (0, 1) 第二个元素
  • (1, 1) 第三个元素
  • (1, 0) 第四个元素

当我们旋转矩阵时,这些元素会移动到新的位置。具体来说:

  • 在无旋转(i = 0)时,元素保持原位,k = j
  • 在旋转90度(i = 1)时,每个元素都向右移动一个位置(如果在最右,则回到最左)。
  • 在旋转180度(i = 2)时,每个元素移动两个位置。
  • 在旋转270度(i = 3)时,每个元素移动三个位置。

k = (i + j) % 4正是实现这种模拟的计算方法。这里的% 4确保了我们总是在0到3的范围内获取索引,对应于2x2矩阵的四个位置。这样,无论我们旋转多少次(90度、180度、270度、或360度/无旋转),每个元素都能被放置到正确的新位置。

示例

假设我们处理的元素是矩阵的(0, 1)位置的元素,即j = 1

  • 无旋转(i = 0),k = (0 + 1) % 4 = 1,元素保持在(0, 1)
  • 旋转90度(i = 1),k = (1 + 1) % 4 = 2,表示原来(0, 1)的元素现在应该移动到第三个位置,即在顺时针旋转90度后的新位置。
  • 旋转180度(i = 2),k = (2 + 1) % 4 = 3,表示元素进一步旋转到第四个位置。
  • 旋转270度(i = 3),k = (3 + 1) % 4 = 0,表示元素最终旋转回第一个位置。

这种使用模运算的方法简洁而强大,能够方便地模拟矩阵在顺时针旋转时元素的位置变化,是处理矩阵旋转问题时的一个常用技巧。


⬅️ 矩阵 🏠 00-刷题理模型 ➡️ 离散化