二维矩阵旋转
假设我们有一个2x2的矩阵如下:
1 2
3 4
我们需要生成这个矩阵通过顺时针旋转90度、180度、270度以及360度(即原矩阵)的所有可能形态,并将每种形态转换为字符串。
首先,初始化dx和dy数组,它们代表矩阵中每个元素的位置偏移量:
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度旋转或无旋转)
在不进行旋转的情况下,我们直接根据dx和dy的顺序访问元素:
直接访问顺序:1 (0,0) -> 2 (0,1) -> 4 (1,1) -> 3 (1,0)
生成的字符串为:"1243"。
顺时针旋转90度
在顺时针旋转90度后,矩阵变为:
3 1
4 2
为了获取这个旋转状态下的字符串,我们需要重新考虑如何通过dx和dy访问元素。旋转后的访问顺序变为:
访问顺序变为: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,表示元素最终旋转回第一个位置。
这种使用模运算的方法简洁而强大,能够方便地模拟矩阵在顺时针旋转时元素的位置变化,是处理矩阵旋转问题时的一个常用技巧。
💬 评论