Leetcode-48-旋转图像

题目说明

给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 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]
]

分析

旋转图像,这个应用在图片处理的过程中,非常常见。我们知道对于计算机而言,图像,其实就是一组像素点的集合(所谓点阵),所以图像旋转的问题,本质上就是一个二维数组的旋转问题。

方法一:数学方法(转置再翻转)

我们可以利用矩阵的特性。所谓顺时针旋转,其实就是先转置矩阵,然后翻转每一行。

代码如下:

public void rotate(int[][] matrix) {int n = matrix.length;// 转置矩阵for (int i = 0; i < n; i++)for (int j = i; j < n; j++) {int tmp = matrix[i][j];matrix[i][j] = matrix[j][i];matrix[j][i] = tmp;}// 翻转行for( int i = 0; i < n; i++ ){for( int j = 0; j < n/2; j++ ){int tmp = matrix[i][j];matrix[i][j] = matrix[i][n-j-1];matrix[i][n-j-1] = tmp;}}
}

复杂度分析
时间复杂度:O(N^2)
这个简单的方法已经能达到最优的时间复杂度O(N^2) ,因为既然是旋转,那么每个点都应该遍历到,N^2的复杂度不可避免。
空间复杂度:O(1)。旋转操作是原地完成的,只耗费常数空间

方法二:分治(分为四部分旋转)

方法 1 使用了两次矩阵操作,能不能只使用一次操作的方法完成旋转呢?
为了实现这一点,我们来研究每个元素在旋转的过程中如何移动。
在这里插入图片描述

这提供给我们了一个思路,可以将给定的矩阵分成四个矩形并且将原问题划归为旋转这些矩形的问题。这其实就是分治的思想。
在这里插入图片描述
具体解法也很直接,可以在每一个矩形中遍历元素,并且在长度为 4 的临时列表中移动它们。

代码如下:

public void rotate(int[][] matrix) {int n = matrix.length;for (int i = 0; i < n / 2 + n % 2; i++) {for (int j = 0; j < n / 2; j++) {int[] tmp = new int[4];int row = i;int col = j;for (int k = 0; k < 4; k++) {tmp[k] = matrix[row][col];// 定位下一个数int x = row;row = col;col = n - 1 - x;}for (int k = 0; k < 4; k++) {matrix[row][col] = tmp[(k + 3) % 4];int x = row;row = col;col = n - 1 - x;}}}
}

复杂度分析
时间复杂度:O(N^2) 是两重循环的复杂度。
空间复杂度:O(1) 由于我们在一次循环中的操作是“就地”完成的,并且我们只用了长度为 4 的临时列表做辅助。

方法三:分治法改进(单次循环内完成旋转)

大家可能也发现了,我们其实没有必要分成4个矩阵来旋转。这四个矩阵的对应关系,其实是一目了然的,我们完全可以在一次循环内,把所有元素都旋转到位。
因为旋转的时候,是上下、左右分别对称的,所以我们遍历元素的时候,只要遍历一半行、一半列就可以了(1/4元素)。
展示代码如下

public void rotate(int[][] matrix) {int n = matrix.length;// 不区分子矩阵,直接遍历每一个元素for( int i = 0; i < (n + 1)/2; i++ ){for( int j = 0; j < n/2; j++ ){int temp = matrix[i][j];  //2,2matrix[i][j] = matrix[n-j-1][i];matrix[n-j-1][i] = matrix[n-i-1][n-j-1];matrix[n-i-1][n-j-1] = matrix[j][n-i-1];matrix[j][n-i-1] = temp;}}
}

复杂度分析
时间复杂度:O(N^2),是两重循环的复杂度。
空间复杂度:O(1)。我们在一次循环中的操作是“就地”完成的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/818466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在横向渗透攻击中寻到一线生机

横向渗透&#xff0c;作为计算机网络中的一种攻击技术&#xff0c;展现出了攻击者如何巧妙地利用同一级别系统间的漏洞和弱点&#xff0c;扩大其网络访问权限。与纵向渗透不同&#xff0c;横向渗透不关注权限的垂直提升&#xff0c;而是更侧重于在同一层级内扩展影响力。 横向…

Python数据容器(一)

一.数据容器入门 1.Python中的数据容器&#xff1a;一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为1个元素&#xff0c;每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等。 2.数据容器根据特点的不同&#xff0c;如&#…

VTK —— 一、Windows10下编译VTK源码,并用Vs2017代码测试(附编译流程、附编译好的库、vtk测试源码)

效果 编译 1、下载VTK8.2.0源码        2、解压源码后&#xff0c;进入目录创建build目录&#xff0c;同时在build内创建install目录 (下图install目录是在cmake第一次后才手动创建&#xff0c;建议在创建build时创建)        3、打开CMake&#xff0c;如下图填入…

卷积神经网络结构组成与解释

卷积神经网络结构组成与解释 卷积神经网络是以卷积层为主的深度网路结构&#xff0c;网络结构包括有卷积层、激活层、BN层、池化层、FC层、损失层等。卷积操作是对图像和滤波矩阵做内积&#xff08;元素相乘再求和&#xff09;的操作。 1. 卷积层 常见的卷积操作如下&#x…

UE5学习日记——实现自定义输入及监听输入,组合出不同的按键输入~

UE5的自定义按键和UE4有所不同&#xff0c;在这里记录一下。 本文主要是记录如何设置UE5的自定义按键&#xff0c;重点是学会原理&#xff0c;实际开发时结合实际情况操作。 输入映射 1. 创建输入操作 输入操作并不是具体的按键映射&#xff0c;而是按键的激活方式&#xff0…

搭建zabbix6.0TLS

创建初始容器 docker run --name php-fpm -p 9000:9000 -d php:fpm创建文件目录 mkdir -p /opt/php/{conf,html} && cd docker/php复制文件 docker cp php-fpm:/usr/local/etc/php-fpm.d/www.conf /opt/php/conf/www.conf docker cp php-fpm:/usr/local/etc/php/ph…

【数据可视化】教程及案例

数据可视化是将数据通过图形、图像等形式直观展现出来的技术&#xff0c;它可以帮助人们更好地理解数据背后的信息和趋势。以下是一些数据可视化的教程和案例资源&#xff0c;以及它们各自的特点和应用场景。 ### 教程资源 1. **Python数据可视化入门教程【3】** - 这些教…

简单高效的GO发票识别+发票查验接口

在这个瞬息万变的商业世界里&#xff0c;商业欺诈如影随形&#xff0c;虚假发票成为企业难以忽视的风险。而发票作为每笔交易的重要凭证&#xff0c;对其进行入账前的真伪查验显得尤为重要。但面对海量的发票查验与发票录入工作&#xff0c;人工手动查验的方式&#xff0c;速度…

Avalonia中MVVM模式下设置TextBox焦点

Avalonia中MVVM模式下设置TextBox焦点 前言引入Nuget库程序里面引入相关库修改前端代码#效果图 前言 我们在开发的过程中,经常会遇到比如我在进入某个页面的时候我需要让输入焦点聚焦在指定的文本框上面,或者点击某个按钮触发某个选项的时候也要自动将输入焦点聚焦到指定的文…

制作一个OpenHarmony视频播放器

简介 媒体子系统是 OpenHarmony 中重要的子系统&#xff0c;可以提供音视频播放能力。媒体子系统为开发者提供一套简单且易于理解的接口&#xff0c;使得开发者能够方便接入系统并使用系统的媒体资源。媒体子系统提供以下常用功能&#xff1a; 音视频播放&#xff08;AVPlaye…

困惑度(Perplexity)的计算方法和意义

困惑度&#xff08;Perplexity&#xff09;是一种用于评估语言模型性能的指标&#xff0c;特别是在自然语言处理领域中。它衡量的是模型对一组样本数据的预测能力&#xff0c;通常用于评估语言模型的预测准确度和泛化能力。 提出契机 困惑度的概念最早是由Jelinek和Mercer在1…

比特币减半:挑战与机遇

比特币减半是加密货币领域中一件备受关注的大事&#xff0c;它不仅影响着比特币本身的发展&#xff0c;也深刻影响着整个加密货币市场的走势。在这个历史性时刻&#xff0c;我们有必要深入分析比特币减半带来的挑战与机遇&#xff0c;以及未来的加密货币发展趋势。 挑战&#x…

【Java框架】Mybatis教程(二)——SQL映射及缓存

目录 SQL传参1.单个简单参数使用1使用2 2.多个简单参数2.1使用索引【不推荐】2.2使用Param 3.复杂参数3.1对象3.2集合(Map) Mybatis中的批量操作1.批量查询1.1数组入参1.2List入参1.3Map中有list入参 SQL映射的XML文件resultMapresultMap属性方式1&#xff1a;在查询时&#xf…

【Entity Framework】聊一聊EF中继承关系

【Entity Framework】聊一聊EF中继承关系 文章目录 【Entity Framework】聊一聊EF中继承关系一、概述二、实体类型层次结构映射三、每个层次结构一张表和鉴别器配置四、共享列五、每个类型一张表配置六、每个具体类型一张表配置七、TPC数据库架构八、总结 一、概述 Entity Fra…

如何实现对空调状态监测的监控

随着科技的飞速发展和人们生活水平的持续提高&#xff0c;空调已经成为现代家庭和办公环境中不可或缺的一部分。然而&#xff0c;传统的空调使用方式往往存在能效低下、操作不便等问题。为了解决这些问题&#xff0c;智能空调控制器应运而生&#xff0c;它不仅能实现对空调状态…

C++内存分区模型

c程序在执行时会将内存划分为四个区域&#xff0c;分别是代码区&#xff0c;全局区&#xff0c;栈区和堆区。 划分的意义&#xff1a; 方便管理资源&#xff1a; 通过划分成不同区域&#xff0c;可以更高效地分配和释放内存。栈上的内存分配和释放是自动进行&#xff0c;而堆…

盘点2024年最新可用免费云服务器

随着云计算技术的快速发展&#xff0c;越来越多的企业和个人开始使用云服务器来满足各种业务需求。云服务器作为云计算的核心服务之一&#xff0c;以其弹性扩展、按需付费等特点受到广泛关注。本文将为大家盘点2024年最新可用免费云服务器&#xff0c;助力大家轻松上云&#xf…

mysql的下载、安装

首先进入官网&#xff1a;MySQL 点击“downloads”进入下载界面 2.往下滑动滚轮&#xff0c;点击“mysql community...&#xff08;公开版&#xff09;” 3.往下滑&#xff0c;找到并单击“install for Windows” 4.选择版本&#xff1a;初学者可以使用较低版本&#xff0c;较…

软件架构静态演化

1.静态演化需求 软件架构静态演化的需求是广泛存在的&#xff0c;可以归结为两个方面。 &#xff08;1&#xff09;设计时演化需求。在架构开发和实现过程中对原有架构进行调整&#xff0c;保证软件实现与架构的一致性以及软件开发过程的顺利进行。 &#xff08;2&#xff09;运…

20240409在全志H3平台的Nano Pi NEO CORE开发板上运行Ubuntu Core16.04时跑通4G模块EC200A-CN【PPP模式】

20240409在全志H3平台的Nano Pi NEO CORE开发板上运行Ubuntu Core16.04时跑通4G模块EC200A-CN【PPP模式】 2024/4/9 14:25 【不建议使用ppp模式&#xff0c;功耗大&#xff0c;貌似更过分的&#xff01;网速还低&#xff01;】 【唯一的优点&#xff1a;ppp模式下是通过脚本配置…