48. 旋转图像(C++)

题目

给定一个 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]]

提示:

n == matrix.length == matrix[i].length

1 <= n <= 20

-1000 <= matrix[i][j] <= 1000

题解

cpp 复制代码
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int m = matrix.size();
        for(int i = 0; i < m; ++i){
            for(int j = i; j < m; ++j){
                swap(matrix[i][j],matrix[j][i]);
            }
        }
        for(int i = 0; i < m; ++i){
            int left = 0, right = m - 1;
            while(left < right){
                swap(matrix[i][left],matrix[i][right]);
                left++;
                right--;
            }

        }
        
    }
};

算法原理

1. 转置矩阵
  • 定义 :转置矩阵是将矩阵的行和列交换,即原矩阵中 matrix[i][j] 的位置变为 matrix[j][i]

  • 几何意义:转置操作相当于将矩阵绕主对角线(从左上到右下)镜像翻转。

  • 代码实现

    cpp 复制代码
    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            swap(matrix[i][j], matrix[j][i]);
        }
    }
    • 外层循环遍历每一行 i
    • 内层循环从 j = i 开始遍历列,避免重复交换元素(如 matrix[i][j]matrix[j][i] 会被交换两次)。
2. 反转每一行
  • 定义:将转置后的矩阵的每一行元素逆序排列。

  • 几何意义:反转行操作相当于将矩阵绕垂直中线(中间列)镜像翻转。

  • 代码实现

    cpp 复制代码
    for (int i = 0; i < n; ++i) {
        int left = 0, right = n - 1;
        while (left < right) {
            swap(matrix[i][left], matrix[i][right]);
            left++;
            right--;
        }
    }
    • 对于每一行 i,使用双指针 leftright 分别指向行的首尾。
    • 交换首尾元素并向中间移动指针,直到指针相遇。

数学推导

  • 顺时针旋转 90 度的坐标变换
    • 原位置 (i, j) 旋转后的坐标为 (j, n-1-i)
  • 转置与反转的组合
    • 转置后(i, j) → (j, i)
    • 反转行后(j, i) → (j, n-1-i)(行反转使 i 变为 n-1-i)。
    • 最终结果与顺时针旋转的坐标变换一致。

示例验证

以示例 1 为例:

cpp 复制代码
原矩阵:
1 2 3
4 5 6
7 8 9

转置后:
1 4 7
2 5 8
3 6 9

反转每一行后:
7 4 1
8 5 2
9 6 3 → 正确结果

复杂度分析

  • 时间复杂度 : O ( n 2 ) O(n^2) O(n2),需遍历矩阵两次。
  • 空间复杂度 : O ( 1 ) O(1) O(1),原地操作无需额外空间。
相关推荐
猷咪16 小时前
C++基础
开发语言·c++
IT·小灰灰16 小时前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧16 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q16 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳016 小时前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾16 小时前
php 对接deepseek
android·开发语言·php
CSDN_RTKLIB16 小时前
WideCharToMultiByte与T2A
c++
2601_9498683616 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计16 小时前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
蒹葭玉树16 小时前
【C++上岸】C++常见面试题目--操作系统篇(第二十八期)
linux·c++·面试