【忍者算法】从照片旋转到矩阵变换:探索图像旋转问题|LeetCode 48 旋转图像
从照片旋转到矩阵变换:探索图像旋转问题
生活中的旋转
在这个自拍时代,我们经常需要调整照片的方向。有时拍出来的照片歪了,需要旋转90度;有时想要换个角度看看效果,来回旋转照片。这种旋转操作不仅存在于我们的日常生活中,在计算机图形学、图像处理等领域也是一个基础且重要的操作。
问题描述
LeetCode第48题"旋转图像"要求我们:给定一个 n × n 的二维矩阵 matrix 表示一个图像,将图像顺时针旋转 90 度。要求必须在原地旋转图像,也就是说,你需要直接修改输入的二维矩阵。
例如:
输入:matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
输出:[[7,4,1],
[8,5,2],
[9,6,3]]
就像我们在手机相册里旋转照片一样,每个像素点都要移动到新的位置,但我们需要保证不使用额外的存储空间!
最直观的解法:辅助数组
最简单的想法就像我们复印一张照片,在新的纸上重新排列像素。虽然这种方法使用了额外空间,不符合题目要求,但它帮助我们理解旋转的本质。
辅助数组的实现
public void rotate(int[][] matrix) {
int n = matrix.length;
// 创建一个新的n×n数组
int[][] temp = new int[n][n];
// 将原矩阵旋转90度后的结果存入临时数组
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 关键转换:第i行第j列的元素,旋转后变成第j行第(n-1-i)列
temp[j][n-1-i] = matrix[i][j];
}
}
// 将结果复制回原矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = temp[i][j];
}
}
}
优化解法:原地旋转
仔细观察,我们发现90度旋转可以通过两步简单的操作完成:先沿对角线翻转,再沿竖直中线翻转。就像折纸一样,通过两次折叠就能达到旋转的效果!
原地旋转的原理
想象你在玩魔方:
- 第一步:沿主对角线翻转(左上到右下的对角线)
- [i,j] 变成 [j,i]
- 第二步:沿竖直中线翻转
- [i,j] 变成 [i,n-1-j]
示例运行
用3×3矩阵来说明:
原始矩阵: 对角线翻转: 竖直中线翻转:
1 2 3 1 4 7 7 4 1
4 5 6 → 2 5 8 → 8 5 2
7 8 9 3 6 9 9 6 3
第一步:对角线翻转
- (1,2)和(2,1)交换
- (1,3)和(3,1)交换
- (2,3)和(3,2)交换
第二步:竖直中线翻转
- 第1列和第3列交换
- 第2列保持不变
Java代码实现
public void rotate(int[][] matrix) {
int n = matrix.length;
// 步骤1:沿主对角线翻转
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// 交换matrix[i][j]和matrix[j][i]
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// 步骤2:沿竖直中线翻转
for (int i = 0; i < n; i++) {
for (int j = 0; j < n/2; j++) {
// 交换matrix[i][j]和matrix[i][n-1-j]
int temp = matrix[i][j];
matrix[i][j] = matrix[i][n-1-j];
matrix[i][n-1-j] = temp;
}
}
}
解法比较
让我们比较这两种方法:
辅助数组法:
- 时间复杂度:O(n²)
- 空间复杂度:O(n²)
- 优点:直观易懂,容易实现
- 缺点:需要额外空间,不满足原地旋转的要求
原地旋转法:
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 优点:不需要额外空间,完美满足题目要求
- 缺点:需要理解矩阵变换的数学原理
实用技巧总结
解决矩阵旋转问题的关键点:
- 观察旋转前后元素位置的对应关系
- 寻找可以分解的子操作(如翻转)
- 正确处理边界情况
- 小心不要重复交换元素
相关的矩阵变换问题:
- 矩阵转置
- 矩阵对称变换
- 顺时针/逆时针旋转任意角度
小结
通过旋转图像这道题,我们学会了如何通过巧妙的数学变换来完成矩阵旋转。这种思维方式不仅能解决算法题,在图像处理、计算机图形学等领域都有广泛应用。记住,当遇到需要变换矩阵的问题时,可以考虑将复杂的变换分解为简单的操作组合,这样往往能得到更优雅的解决方案!
作者:忍者算法
公众号:忍者算法
我准备了一份刷题清单,以及这些题目的详细题解,覆盖了绝大部分常见面试题。我可以很负责任地说,只要你把这些题真正掌握了,80%的算法面试都能遇到相似题目。公众号回复【刷题清单】获取~
【忍者算法】从照片旋转到矩阵变换:探索图像旋转问题|LeetCode 48 旋转图像的更多相关文章
- 前端与算法 leetcode 48. 旋转图像
目录 # 前端与算法 leetcode 48. 旋转图像 题目描述 概要 提示 解析 解法一:转置加翻转 解法二:在单次循环中旋转 4 个矩形 算法 传入测试用例的运行结果 执行结果 GitHub仓库 ...
- PIE SDK图像旋转
1.算法功能简介 图像旋转可使图像以中心点为轴沿特定方向旋转指定的角度. PIESDK支持算法功能的执行,下面对图像旋转算法功能进行介绍. 2.算法功能实现说明 2.1 实现步骤 第一步 算法参数设置 ...
- osg矩阵变换节点-----平移旋转缩放
osg矩阵变换节点-----平移旋转缩放 转自:http://www.cnblogs.com/ylwn817/articles/1973396.html 平移旋转缩放这个三个是osg矩阵操作中,最常见 ...
- WebGl 旋转(矩阵变换)
代码1: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- FPGA算法学习(1) -- Cordic(圆周系统之旋转模式)
三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...
- 【转】 CATransform3D 矩阵变换之立方体旋转实现细节
原文网址:http://blog.csdn.net/ch_soft/article/details/7351896 第一部分.前几天做动画,使用到了CATransform3D ,由于没有学过计算机图形 ...
- 每日算法37:Rotate Image (图像旋转)
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- CATransform3D 矩阵变换之立方体旋转实现细节 (转)
原文地址 http://blog.csdn.net/ch_soft/article/details/7351896 第一部分.前几天做动画,使用到了CATransform3D ,由于没有学过计算机图形 ...
- [google面试CTCI] 1-6.图像旋转问题
[字符串与数组] Q:Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, wr ...
- 图像旋转、伸缩的自写matlab实现
一.图像的旋转 今天的代码不是自己写的,缺少一些时间.但是认认真真推导了一下旋转的公式,代码的思想与原博博主一致,致敬! 愚以为,自己来实现图像旋转算法的关键点有二:其一,确定旋转后的图像边界.其二, ...
随机推荐
- Linux常用系统性能监控工具
top 首先关于top命令,我想大家应该都挺熟悉的了. Linux系统下的top命令有点类似于Windows系统里的任务管理器,能够实时动态地给出系统中各个进程的资源占用状况,是Linux下比较常用的 ...
- Educational Codeforces Round 77 (Rated for Div2)
B - Obtain Two Zeroes 给定两个整数\(a,b\),你可以执行以下操作任意次:每次操作选择一个正整数\(x\),使得\(a:=a-x,b:=b-2x\)或者\(a:=a-2x,b: ...
- 1分钟学会如何提升PCIe通信速率,基于RK3568J + FPGA国产平台!
测试数据汇总 表 1 PCIe总线介绍 PCIe,即PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准.主要用 ...
- PythonDay3Advance
PythonDay3Advance 运算符 位运算符 进制: 将整数分了几种进制表示法 二进制:由0,1构成,逢2进1,以0b开头 八进制:由0,1,2,3,4,5,6,7构成,逢8进1,以0开头 十 ...
- Jetpack Compose学习(15)——Pager组件的使用(对标ViewPager)
原文地址: Jetpack Compose学习(15)--Pager组件的使用(对标ViewPager)-Stars-One的杂货小窝 从名字可以看出,Pager这个就是ViewPager的替代产物 ...
- 09C++选择结构(3)
一.求3个整数中最小值 题目:输入三个整数,表示梨的重量,输出最小的数. 方法1:经过三次两两比较,得出最小值. a<=b && a<=c min=a b<=c &a ...
- 使用archlinux AUR源下载安装的方法 以及 解决makepkg网络连接超时(time out)的问题
1.使用archlinux(AUR)源下载安装软件/驱动的方式 2.解决使用此方时无法通过网络下载资源文件的问题(网络连接超时/time out) 1.使用archlinux(AUR)源下载安装软件/ ...
- MySQL启动时自动创建数据库
一.背景及分析 MysqL容器启动时,会自动创建一些必要的数据库,比如MysqL,这是官方默认的做法.但是,在实际中,还需要让MysqL自动创建我们自定义的数据库.本文就此应用场合进行探究. 一般的做 ...
- IDEA利用阿里云插件部署Springboot项目
下载插件 搜索 Alibaba Cloud Toolkit 插件,并安装. IDEA增加Run/Debug Configurations Add New Configuration - Deploy ...
- 一句话,我让 AI 帮我做了个 P 图网站!
每到过节,不少小伙伴都会给自己的头像 P 个图,加点儿装饰. 比如圣诞节给自己头上 P 个圣诞帽,国庆节 P 个小红旗等等.这是一类比较简单.需求量却很大的 P 图场景,也有很多现成的网站和小程序,能 ...