这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入: matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出: [[7,4,1],[8,5,2],[9,6,3]]
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
示例 3:
输入:matrix = [[1]]
输出:[[1]]
示例 4:
输入:matrix = [[1,2],[3,4]]
输出:[[3,1],[4,2]]
链接:leetcode-cn.com/problems/ro…
题解
通过观察旋转前后的数组, 我们可以得到如下的结论:
假设旋转前数组用 matrix 表示, 旋转后数组用 matrix' 来表示, 对于原数组中元素 matrix[i][j], 旋转后则对应于 matrix'[j][n-1-i], 我们可以用 matrix'[j][n-1-i] = matrix[i][j] 来表示.
这是个很重要的特征. 因为题目要求我们必须在 matrix 中做交换, 所以我们不能新建 matrix' 数组. 那怎么办呢? 旋转操作总是很难去模拟, 我们可以另想一种方法来代替旋转, 最常见的代替旋转的方法就是翻转.
在这道题目中, 代替旋转90度的方法就是先水平翻转,再根据主对角线翻转. 我们可以根据数学的公式来证明这种翻转是有效的. 首先水平反转时, 有 matrix[n-1-i][j] = matrix[i][j], 可以看到, 水平翻转之后的行和列对应的数字是旋转之后的列和行对应的数字, 只需要再在主对角线上翻转, 即 matrix[j][n-1-i] = matrix[n-1-i][j]. 具体代码如下.
时间复杂度 O(n²), 空间复杂度 O(1)
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
var rotate = function(matrix) {
const swap = (i, j, a, b) => {
const tmp = matrix[i][j]
matrix[i][j] = matrix[a][b]
matrix[a][b] = tmp
}
const n = matrix.length
for (let i = 0; i < n / 2; ++i) {
for (let j = 0; j < n; ++j) {
swap(i, j, n - i - 1, j)
}
}
for (let i = 0; i < n; ++i) {
for (let j = 0; j < i; ++j) {
swap(i, j, j, i)
}
}
};