"You are never too old to set another goal or to dream a new dream." - C.S. Lewis
1. 题目描述
2. 题目分析与解析
2.1 思路一
还是最简单的尝试模拟人的思维,如果对于一个普通人解决该题目,那就是先把第一行放在最后一列 或者 把第一列倒序放在第一行,接着第二行放在倒数第二列 或者 把第二列逆序放在第二行,以此类推。
但是这样解决是有一个棘手的问题,因为题目提醒我们”原地旋转,直接修改输入的二维矩阵,请不要 使用另一个矩阵来旋转图像”。如果按照我们上述的解法,把某一行或者某一列放在另外某一行或者某一列,那么被填充的部分数据就被覆盖,在后续使用时就无法获取到,所以这种方法是不可行的。
但是我们再来观察一下矩阵:
如果将它转置会得到下图:
而我们需要的是下图:
有没有发现点什么?是不是把矩阵一转置在经过一些列次序变换就能得到结果了?(其实我开始也没想到转置,确实对于矩阵还不够敏感)
所以有了上述思路后,代码思路就比较简单了。
代码思路:
-
将矩阵先进行转置
-
转置其实就是按照主轴反转如下:
-
这个转置过程只需要遍历矩阵的一半元素,将遍历到的每一个元素与它需要对应的元素做一次交换就可以了。
-
-
把第一列移动到最后一列,第二列移动到倒数第二列,其实也就是每一行逆序,就可以得到答案。
3. 代码实现
4. 相关复杂度分析
为了分析这段代码的时间和空间复杂度,我们需要考虑每一步操作对输入矩阵的影响。这段代码实现了一个矩阵的顺时针旋转90度的操作,分为两个主要步骤:矩阵的转置和水平翻转(或列的交换)。输入矩阵为 n x n
(因为旋转操作通常在正方形矩阵上进行)。
第1步:矩阵转置
在矩阵转置步骤中,我们遍历了矩阵的上半部分(不包括对角线),对于每一个元素 matrix[i][j]
,我们将其和 matrix[j][i]
交换。这个操作只涉及到读取和写入矩阵元素,没有使用额外的存储空间(除了用于交换的临时变量 temp
)。
-
时间复杂度: 对于一个
n x n
的矩阵,这一步的时间复杂度是O(n^2)
。尽管我们只遍历了矩阵的一半,但遍历的总元素数量仍然与矩阵的总元素数量成正比(大约是n^2 / 2
),这意味着时间复杂度保持为O(n^2)
。 -
空间复杂度: 由于我们只使用了固定数量的变量(
temp
),这一步的空间复杂度是O(1)
。
第2步:水平翻转(或列的交换)
在这一步中,代码提供了两种方法来实现旋转的第二部分。不过,这两种方法的复杂度是相同的。
-
水平翻转:我们遍历矩阵的每一行,将每一行的元素按列进行逆序交换。
-
列的交换:我们遍历矩阵的一半列,将每一列的元素与对应的对面列的元素进行交换。
无论采用哪种方法,操作的总次数都与矩阵中元素的总数成正比。
-
时间复杂度: 对于一个
n x n
的矩阵,这一步的时间复杂度也是O(n^2)
。我们需要对每个元素进行操作,尽管是分行或分列操作,总的操作次数仍然与n^2
成正比。 -
空间复杂度: 同样,由于我们只使用了固定数量的变量(
temp
),这一步的空间复杂度是O(1)
。
总结
-
总时间复杂度:
O(n^2)
。这是因为我们需要对矩阵中的每个元素至少进行一次操作。 -
总空间复杂度:
O(1)
。除了输入矩阵之外,我们只使用了常数空间(临时变量)来执行所有操作。
5. 原地旋转(补充)
以下内容引自力扣官方题解(侵权请告知,立删除)
(个人感觉这种方法很巧妙,虽然开始也想到了但是当时被难在移动哪些元素上,看来还是要多动手把发现的规律写一写,尝试把规律变换成数学语言才能进行编程)看解析之前先看一下下面两个图片:
这种思路的困难之处就是用数学语言写出移动规律(毕竟计算机不能懂规律只能靠数学告诉它规律),以及需要移动哪些元素,由于官方确实讲的比较清晰因此直接截图了:
注释:在下面方法中提到的关键等式
还是得多动手多换角度思考啊!学会用数学!