题目:矩阵旋转

难度:Medium

题目内容

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Note:

You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

翻译:你有一个n*n 的2D矩阵表示一个图像。

将图像旋转90度(顺时针)。

注意:

你必须在原地旋转图像,这意味着你必须直接修改输入2D矩阵。不要分配另一个2D矩阵并进行旋转。

Example 1:

Given input matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
], rotate the input matrix in-place such that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]

Example 2:

Given input matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
], rotate the input matrix in-place such that it becomes:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
 

我的思路:旋转90°,那就是把矩阵分为四块,只对第一块进行循环,然后用第一块的元素下标【i】【j】的表达式分别表示其他块的对应元素,然后把四个元素进行交换即可。

先将矩阵分为如下四块:

A B

C D

现在对A内元素进行循环,其元素下标表示为【i】【j】

1、将A的此元素用temp存储起来,

2、A的此元素取C区域对应的元素值,C区对应元素表示为A元素“先关于矩阵主对角线取对称,然后再取纵向中心对折”

  主对角线取对称,就是【i】【j】=》【j】【i】

  纵向中心对折,就是【i】【j】=》【n-1- i 】【j】

3、C区此元素取D区域对应的元素值,D区对应元素表示为A元素的中心对称,即“先关于横向中心对折,然后再取纵向中心对折”

  横线中心对折,就是【i】【j】=》【i】【n-1- j】

4、D区此元素取B区域对应的元素值,B区对应元素表示为A元素“先关于横向中心对折,然后再取矩阵副对角线对称”

  副对角线对称,就是【i】【j】=》【n-1-j】【n-1-i】

5、B区此元素取之前A区的值,即为 temp ,到此一轮交换结束。

需要注意的是,当矩阵的大小是偶数的时候,此时行数的对称中心 x 为对称线的上面的一个。

例如:

0

1

2

3   此时的 x = n-1 = 1,此时是需要进行交换的行范围是【0~x】,列范围也是【0~x】

  而如果是奇数,则行范围是【0~x-1】,列范围没变还是【0~x】

所以循环的时候需要注意判断奇偶,然后跳过。

我的代码:

     public void rotate(int[][] matrix) {
int n = matrix.length;
if (n <= 1) {
return;
} int even = 1;
if (matrix.length % 2 == 1) {
even = 0;
} int x = (n-1)/2;
for (int i = 0; i <= x; i++) {
for (int j = 0; j <= x; j++) {
if (even==0 && i==x) {
continue;
}
int temp = matrix[i][j];
matrix[i][j] = matrix[n-1-j][i];
matrix[n-1-j][i] = matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j] = matrix[n-1-(n-1-j)][n-1-i];
matrix[n-1-(n-1-j)][n-1-i] = temp;
}
}
}

我的复杂度:O(N2

编码过程中的问题

1、应该使用A的元素下标【i】【j】去表示其他块所有,而不是用相对位置;

2、对“对称”“对折”的下标变化不熟悉,导致浪费不少时间;(还想了半天用 2x - i + even 来表示,其实直接 n-1-i 即可)

3、之前没考虑到矩阵奇偶对循环范围的影响,导致奇数的对称线没有交换;

4、当方法定义返回为void的时候,需要直接返回,写return就行。

答案代码

     public void rotate(int[][] matrix) {
int n = matrix.length;
if (n <= 1) {
return;
} int x = (n-1)/2;
for (int i = 0; i <= x; i++) {
int[] tmp = matrix[i];
matrix[i] = matrix[n-1-i];
matrix[n-1-i] = tmp;
} 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;
}
}
}

答案复杂度:O(N2

答案思路

首先将整个数组上下对称交换:

1 2 3     7 8 9
4 5 6 => 4 5 6
7 8 9 1 2 3

然后再关于主对角线对称交换:

7 8 9     7 4 1
4 5 6 => 8 5 2
1 2 3 9 6 3

优点:逻辑清晰明了

缺点:复杂度比我的方法高一点

 

扩展

逆时针旋转90°?

我的方法——ABCD块之间的取值关系会发生变化。

答案方法——有两种修改方法都行:

      a:第一步和第二步交换,即先对角线,后对折

      b:把第一步的上下对称交换改成左右对称交换,第二步不变。

LeetCode第[48]题(Java):Rotate Image的更多相关文章

  1. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  2. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  3. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  4. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  5. LeetCode第[11]题(Java):Container With Most Water 标签:Array

    题目难度:Medium Given n non-negative integers a1, a2, ..., an, where each represents a point at coordina ...

  6. LeetCode第[4]题(Java):Median of Two Sorted Arrays 标签:Array

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  7. LeetCode第[29]题(Java):Divide Two Integers

    题目:两整数相除 难度:Medium 题目内容: Given two integers dividend and divisor, divide two integers without using ...

  8. LeetCode第[11]题(Java):Container With Most Water (数组容器盛水)——Medium

    题目难度:Medium Given n non-negative integers a1, a2, ..., an, where each represents a point at coordina ...

  9. LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

随机推荐

  1. delphi ---ttoolbar,ttoolbutton

    1.button style:tbsButton,tbsCheck,tbsDivider,tbsDropDown,tbsSeparator,tbsTextButton tbsButton:普通的控件 ...

  2. 利用epoll实现异步IO

    之前异步IO一直没搞明白,大致的理解就是在一个大的循环中,有两部分:第一部分是监听事件:第二部分是处理事件(通过添加回调函数的方式).就拿网络通信来说,可以先通过调用 select 模块中的 sele ...

  3. Web页面性能优化(YSlow)

    YSlow(解析为Why Slow)是雅虎基于网站优化规则推出的工具,帮助你分析并优化网站性能.旧版Yslow 有13条规则,新版Yslow有23项规则,YSlow会根据这些规则分析你的网站,并给出评 ...

  4. 用python合并N个不同字符集编码的sql文件的实践

    背景:我有一项工作任务是将svn某文件夹日常更新的sql文件(归类到日期命名的文件夹中)拿到数据库中运行. 一開始,我是先把sql文件update下来,用notepad++打开,拷贝每个文本的sql语 ...

  5. 让你的代码量减少3倍!使用kotlin开发Android

    (一) 创建Kotlin工程 (二) –秘笈!扩展函数 (三) 缩短五倍的Java Bean 本项目使用的代码地址

  6. PyNest——part 3: connecting networks with synapses

    part 3: connecting networks with synapses parameterising synapse models NEST提供了各种不同的突触模型. 您可以使用命令nes ...

  7. mysql-5.6.22的安装步骤

    一.环境与下载地址: 1.系统下载地址: http://mirrors.sohu.com/centos/6.6/isos/x86_64/CentOS-6.6-x86_64-bin-DVD1.iso 2 ...

  8. C#数组的笔记

    Array.Copy的笔记: 1.将值类型的元素装箱位引用类型的元素,比如讲一个Int32[]的元素复制到Object[]中 2.将引用类型的元素拆箱为值类型的元素 3.加宽CLR基元值类型,比如讲一 ...

  9. day5笔记 列表 list 增删改查

    列表的使用 一.索引和切片 # 索引和切片,用法与字符串一样 l = [1,2,3,'af','re',4,'45'] print(l[0]) print(l[3]) print(l[-1]) # ' ...

  10. MAC 终端terminal颜色

    Mac终端terminal颜色实在太单调了,安装Linux使用的GNU Coreutils替换Mac的ls命令: Mac终端terminal颜色实在太单调了,安装Linux使用的GNU Coreuti ...