解法一:两次翻转
先沿右上 - 左下的对角线翻转(270°+ 一次镜像),再沿水平中线上下翻转(−180°+ 一次镜像),可以实现顺时针 90 度的旋转效果
func rotate(matrix [][]int) {
// 沿着右下对角线翻转矩阵
for i := 0; i<len(matrix); i++{
for j := i; j<len(matrix[i]); j++{
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
}
}
// 翻转矩阵的每一行
for r := 0; r<len(matrix); r++{
reverseRow(matrix[r])
}
}
func reverseRow(nums []int){
left, right := 0, len(nums)-1
for left < right{
nums[left], nums[right] = nums[right], nums[left]
left++
right--
}
}
额外再解释一下如何沿主对角线翻转
for i := 0; i < n; i++
外层循环控制行索引 i,从第 0 行开始,逐行向下遍历,直到第 n - 1 行。这里的 n 是矩阵的行数(由于是方阵,也是列数)。
for j := i; j < n; j++
内层循环控制列索引 j,它从当前行索引 i 开始,逐列向右遍历,直到第 n - 1 列。这样做的原因是:
- 避免重复交换:如果
j从 0 开始遍历,那么在交换matrix[i][j]和matrix[j][i]之后,后续当j增大到i时,又会再次交换matrix[j][i]和matrix[i][j],这就相当于把之前交换的操作又换回来了,导致最终矩阵没有发生变化。因此,为了避免重复交换,j从i开始,只对主对角线右上方的元素进行交换操作。 - 确保只处理一次交换:主对角线(即
i == j)上的元素不需要交换,因为交换matrix[i][i]和matrix[i][i]是没有意义的。所以,j从i开始可以跳过主对角线上的元素,只处理主对角线右上方的元素。