【LeetCode】48. 旋转图像

leetcode

 

解题思路

要实现图像顺时针旋转 90 度,核心是找到坐标变换规律。通过分析发现:

  1. ​​转置操作​​:行列互换(matrix[i][j] ↔ matrix[j][i]
  2. ​​水平翻转​​:每行元素首尾对调(matrix[i][j] ↔ matrix[i][n-1-j]

这两个操作的组合等价于顺时针旋转 90 度:

  • ​​数学证明​​:原始位置 (i, j) → 转置后 (j, i) → 水平翻转后 (j, n-1-i),这正是顺时针旋转的目标位置。

关键步骤

  1. ​​矩阵转置​​:

    • 遍历上三角区域(避免重复交换)
    • 交换 matrix[i][j] 和 matrix[j][i]i 为行,j 从 i+1 开始)
  2. ​​水平翻转每行​​:

    • 对每一行,用双指针从两端向中间交换元素
    • 交换 matrix[i][j] 和 matrix[i][n-1-j]j 只需遍历前半行)

代码实现

func rotate(matrix [][]int) {
    n := len(matrix)

    // 1. 矩阵转置(只遍历上三角)
    for i := 0; i < n; i++ {
        for j := i + 1; j < n; j++ {
            // 交换对称元素
            matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
        }
    }

    // 2. 水平翻转每一行
    for i := 0; i < n; i++ {
        left, right := 0, n-1
        for left < right {
            // 双指针首位交换
            matrix[i][left], matrix[i][right] = matrix[i][right], matrix[i][left]
            left++
            right--
        }
    }
}

示例测试

func main() {
    // 示例 1
    matrix1 := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
    rotate(matrix1)
    fmt.Println("示例1:", matrix1) // [[7 4 1] [8 5 2] [9 6 3]]

    // 示例 2
    matrix2 := [][]int{
        {5, 1, 9, 11},
        {2, 4, 8, 10},
        {13, 3, 6, 7},
        {15, 14, 12, 16},
    }
    rotate(matrix2)
    fmt.Println("示例2:", matrix2) // [[15 13 2 5] [14 3 4 1] [12 6 8 9] [16 7 10 11]]
}

复杂度分析

  • ​​时间复杂度​​:O(n²)
    转置操作遍历 n(n-1)/2 次,水平翻转遍历 n²/2 次,总计 O(n²)
  • ​​空间复杂度​​:O(1)
    仅用常数级临时变量(无额外数据结构)

关键点总结

    1. ​​操作顺序不可逆​​:必须先转置再水平翻转,反之会得到不同结果
    2. ​​转置优化​​:只遍历上三角区域(j = i+1 开始),避免重复交换
    3. ​​翻转效率​​:水平翻转使用双指针,比逐行反转减少 50% 交换次数
    4. ​​坐标映射关系​​:原始位置 (i,j) → 目标位置 (j, n-1-i)
    5. ​​替代方案​​:逐层旋转法(按圈处理四元素组)虽同样 O(n²),但坐标计算更复杂
posted @ 2025-06-13 12:37  云隙之间  阅读(25)  评论(0)    收藏  举报