当前位置: 首页 > news >正文

LeetCode 48 - 旋转图像算法详解(全网最优雅的Java算法

文章目录

  • LeetCode 48 - 旋转图像算法详解
    • 题目描述
      • 示例 1:
      • 示例 2:
    • 算法思路
      • 核心观察
      • 变换过程可视化
        • 原始矩阵
        • 步骤1:转置矩阵
        • 步骤2:水平翻转每一行
        • 最终结果
    • 算法实现
      • Python实现
      • Java实现(Java最优雅算法,强力推荐!!)
      • C++实现
    • 复杂度分析
      • 时间复杂度
      • 空间复杂度
    • 关键技巧
      • 1. 转置时的遍历优化
      • 2. 变换顺序的重要性
    • 其他旋转方向
      • 逆时针旋转90度
      • 旋转180度
    • 测试用例
      • 测试代码
    • 总结

LeetCode 48 - 旋转图像算法详解

题目描述

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

算法思路

核心观察

顺时针旋转90度可以通过两步变换实现:

  1. 转置矩阵:将 matrix[i][j] 与 matrix[j][i] 交换
  2. 水平翻转:将每一行从左到右翻转

变换过程可视化

以示例1为例,展示完整的变换过程:

原始矩阵
位置(0,0)(0,1)(0,2)
元素123
位置(1,0)(1,1)(1,2)
元素456
位置(2,0)(2,1)(2,2)
元素789
步骤1:转置矩阵

转置规则:matrix[i][j] ↔ matrix[j][i]

位置(0,0)(0,1)(0,2)
元素147
位置(1,0)(1,1)(1,2)
元素258
位置(2,0)(2,1)(2,2)
元素369

转置操作示意:

  • (0,1)的2 ↔ (1,0)的4
  • (0,2)的3 ↔ (2,0)的7
  • (1,2)的6 ↔ (2,1)的8
步骤2:水平翻转每一行

每行内部元素位置交换:

行号翻转前翻转后
第0行[1, 4, 7][7, 4, 1]
第1行[2, 5, 8][8, 5, 2]
第2行[3, 6, 9][9, 6, 3]
最终结果
位置(0,0)(0,1)(0,2)
元素741
位置(1,0)(1,1)(1,2)
元素852
位置(2,0)(2,1)(2,2)
元素963

算法实现

Python实现

def rotate(matrix):"""顺时针旋转90度 - 两步法时间复杂度: O(n²)空间复杂度: O(1)"""n = len(matrix)# 步骤1: 转置矩阵for i in range(n):for j in range(i + 1, n):  # 只遍历上三角,避免重复交换matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]# 步骤2: 水平翻转每一行for i in range(n):matrix[i].reverse()  # 或者手动实现: matrix[i] = matrix[i][::-1]# 手动实现水平翻转的版本
def rotate_manual_flip(matrix):"""顺时针旋转90度 - 手动实现翻转"""n = len(matrix)# 步骤1: 转置矩阵for i in range(n):for j in range(i + 1, n):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]# 步骤2: 手动水平翻转每一行for i in range(n):left, right = 0, n - 1while left < right:matrix[i][left], matrix[i][right] = matrix[i][right], matrix[i][left]left += 1right -= 1

Java实现(Java最优雅算法,强力推荐!!)

public void rotate(int[][] matrix) {int n = matrix.length;// 步骤1: 转置矩阵for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {int temp = matrix[i][j];matrix[i][j] = matrix[j][i];matrix[j][i] = temp;}}// 步骤2: 水平翻转每一行for (int i = 0; i < n; i++) {int left = 0, right = n - 1;while (left < right) {int temp = matrix[i][left];matrix[i][left] = matrix[i][right];matrix[i][right] = temp;left++;right--;}}
}

C++实现

void rotate(vector<vector<int>>& matrix) {int n = matrix.size();// 步骤1: 转置矩阵for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {swap(matrix[i][j], matrix[j][i]);}}// 步骤2: 水平翻转每一行for (int i = 0; i < n; i++) {reverse(matrix[i].begin(), matrix[i].end());}
}

复杂度分析

时间复杂度

  • 转置操作: O(n²/2) ≈ O(n²)
  • 水平翻转: O(n²/2) ≈ O(n²)
  • 总计: O(n²)

空间复杂度

  • O(1): 只使用常数级额外空间,满足原地操作要求

关键技巧

1. 转置时的遍历优化

# ✅ 正确:只遍历上三角
for i in range(n):for j in range(i + 1, n):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]# ❌ 错误:会重复交换,相当于没有操作
for i in range(n):for j in range(n):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

2. 变换顺序的重要性

# ✅ 正确顺序:先转置,再水平翻转 = 顺时针90度
transpose(matrix)
horizontal_flip(matrix)# ❌ 错误顺序:先水平翻转,再转置 = 逆时针90度
horizontal_flip(matrix)
transpose(matrix)

其他旋转方向

逆时针旋转90度

def rotate_counterclockwise(matrix):n = len(matrix)# 先水平翻转,再转置for i in range(n):matrix[i].reverse()for i in range(n):for j in range(i + 1, n):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

旋转180度

def rotate_180(matrix):n = len(matrix)# 水平翻转 + 垂直翻转matrix.reverse()  # 垂直翻转for row in matrix:row.reverse()  # 水平翻转

测试用例

测试代码

def test_rotate():# 测试用例1: 3x3矩阵matrix1 = [[1,2,3],[4,5,6],[7,8,9]]rotate(matrix1)expected1 = [[7,4,1],[8,5,2],[9,6,3]]assert matrix1 == expected1# 测试用例2: 4x4矩阵matrix2 = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]rotate(matrix2)expected2 = [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]assert matrix2 == expected2# 测试用例3: 1x1矩阵matrix3 = [[1]]rotate(matrix3)expected3 = [[1]]assert matrix3 == expected3# 测试用例4: 2x2矩阵matrix4 = [[1,2],[3,4]]rotate(matrix4)expected4 = [[3,1],[4,2]]assert matrix4 == expected4print("所有测试用例通过!")# 运行测试
test_rotate()

总结

旋转图像问题的关键在于发现两步变换法

  1. 转置矩阵 - 将行列坐标互换
  2. 水平翻转 - 将每行左右翻转

这种方法简洁高效,时间复杂度O(n²),空间复杂度O(1),完美满足原地操作的要求。

掌握这个技巧后,各种角度的旋转都可以通过类似的变换组合来实现!


文章转载自:

http://PG2gtu5T.ntqgz.cn
http://URDs8WYu.ntqgz.cn
http://5TpmxWb6.ntqgz.cn
http://DL2Kt2w2.ntqgz.cn
http://w1Q3Ywh7.ntqgz.cn
http://B12NZX6D.ntqgz.cn
http://8DMK8QGQ.ntqgz.cn
http://YcggIrxY.ntqgz.cn
http://j4FCMicu.ntqgz.cn
http://AkRCXAQR.ntqgz.cn
http://bYCpmtG0.ntqgz.cn
http://tikSjaii.ntqgz.cn
http://OwDnSxMQ.ntqgz.cn
http://cpAV4EMA.ntqgz.cn
http://4eSWOrR5.ntqgz.cn
http://q06mqfVJ.ntqgz.cn
http://2urvcwsu.ntqgz.cn
http://KJHFu6lY.ntqgz.cn
http://ABPoOha3.ntqgz.cn
http://a2omQOC6.ntqgz.cn
http://4AkPy8pm.ntqgz.cn
http://QSuByirv.ntqgz.cn
http://WSrgLmqc.ntqgz.cn
http://aOCqvxHW.ntqgz.cn
http://TVLaSUMn.ntqgz.cn
http://FXfrFN0i.ntqgz.cn
http://VRt6RxzG.ntqgz.cn
http://TvaEN9gF.ntqgz.cn
http://STaY4iNR.ntqgz.cn
http://nkDlu5QW.ntqgz.cn
http://www.dtcms.com/a/367414.html

相关文章:

  • ResNet(残差网络)-彻底改变深度神经网络的训练方式
  • Docker多阶段构建Maven项目
  • 山姆·奥特曼 (Sam Altman) 分享提高工作效率的方法
  • 【赛题已出】2025高教社杯全国大学生数学建模竞赛ABCDE赛题已发布!
  • Git的强软硬回退(三)
  • 网络计算工具ipcalc详解
  • rabbitmq 入门知识点
  • C++ 中基类和派生类对象的赋值与转换
  • STM32F103_Bootloader程序开发15 - 从Keil到vscode + EIDE + GCC的迁移实践
  • 神马 M21 31T 矿机解析:性能、规格与市场应用
  • 解析 Quartz 报错:Table ‘test.QRTZ_LOCKS‘ doesn‘t exist 的解决方案
  • 【高等数学】第十一章 曲线积分与曲面积分——第二节 对坐标的曲线积分
  • 产品推荐|千眼狼宽光谱高速摄像机NEO系列
  • ECIES实现原理
  • Linux安装RTL8821CE无线网卡驱动
  • 下载及交叉编译libconfig
  • AutoLayout与Masonry:简化iOS布局
  • 《计算机网络安全》实验报告一 现代网络安全挑战 拒绝服务与分布式拒绝服务攻击的演变与防御策略(2)
  • upload-labs通关笔记-第17关文件上传关卡之二次渲染jpg格式
  • 人工智能机器学习——逻辑回归
  • Java Web 是技术与产业的 “交叉赋能点”
  • Linux笔记---UDP套接字实战:简易聊天室
  • 新增MCP工具管理,AI对话节点新增工具设置,支持对接企业微信机器人,MaxKB v2.1.0版本发布
  • 2025年数学建模国赛C题超详细解题思路
  • 【论文阅读】-《Besting the Black-Box: Barrier Zones for Adversarial Example Defense》
  • 小迪web自用笔记27
  • 不会战略、不会融资、不会搭团队?别叫自己 CTO
  • ⸢ 肆 ⸥ ⤳ 默认安全建设方案:b.安全资产建设
  • 【高分论文密码】大尺度空间模拟预测与数字制图
  • 机器翻译:腾讯混元团队开源的模型 Hunyuan-MT 详解