这是我参与11月更文挑战的22天,活动详情查看:2021最后一次更文挑战。
前言
一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,希望通过这种方式养成持续学习的习惯。因为我是做iOS开发的,主要是用Objective-C语言,最近也在学习Swift,所以本系列的题解都将使用swift语言完成,本文更新的是LeetCode中HOT100的第22题048 旋转图像。
题目
给定一个 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]]
提示:
1. matrix.length == n
2. matrix[i].length == n
3. 1 <= n <= 20
4. -1000 <= matrix[i][j] <= 1000
分析
本题的意思很简单,将一个 的矩阵顺时针旋转90度。因为必须在原数组上进行处理,所以我们可以将矩阵进行分层,第一层是最外围的一圈,第二层是次外围的一圈,如下图红色方框所示,然后对每一层中的元素一次进行旋转。
因为是在原矩阵上进行旋转,我们发现每一个元素的旋转都涉及到4个元素,如下面红色和绿色圆圈对应的4各元素就是第一层和第二层中某个元素在旋转中分别涉及到的4个元素。\
- 因为每一层由两行两列组成,所以 矩阵可以分为 层
- 第 i 层中每一边的元素个数为, 需要处理的元素个位为 个
- 下标为的元素,其旋转一周的处理方法如下:
let temp = matrix[row][col]
matrix[row][col] = matrix[maxIndex - col][row] //1. 左 --> 上
matrix[maxIndex - col][row] = matrix[maxIndex - row][maxIndex - col] //2. 下 --> 左
matrix[maxIndex - row][maxIndex - col] = matrix[col][maxIndex - row] //3. 右 --> 下
matrix[col][maxIndex - row] = temp //4. 上 --> 右
题解
class KLLC048 {
func rotate(_ matrix: inout [[Int]]) {
if matrix.count <= 1 {
return
}
let n = matrix.count
let maxIndex = n - 1
//处理的层数为 n/2,依次为第(1,maxIndex-1)行,第(2,maxIndex-2)行...
for row in 0..<(n>>1) {
//每一层依次处理第i行的 [i, maxIndex-i)的元素,每个元素进行顺时针旋转一圈
for col in row..<(maxIndex - row) {
let temp = matrix[row][col]
//顺时针旋转一圈
matrix[row][col] = matrix[maxIndex - col][row] //1. 左 --> 上
matrix[maxIndex - col][row] = matrix[maxIndex - row][maxIndex - col] //2. 下 --> 左
matrix[maxIndex - row][maxIndex - col] = matrix[col][maxIndex - row] //3. 右 --> 下
matrix[col][maxIndex - row] = temp //4. 上 --> 右
}
}
}
}