rotate image java_LeetCode第[48]题(Java):Rotate Image

题目:矩阵旋转

难度: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】

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

我的代码:

1 public void rotate(int[][] matrix) {2 int n =matrix.length;3 if (n <= 1) {4 return;5 }6

7 int even = 1;8 if (matrix.length % 2 == 1) {9 even = 0;10 }11

12 int x = (n-1)/2;13 for (int i = 0; i <= x; i++) {14 for (int j = 0; j <= x; j++) {15 if (even==0 && i==x) {16 continue;17 }18 int temp =matrix[i][j];19 matrix[i][j] = matrix[n-1-j][i];20 matrix[n-1-j][i] = matrix[n-1-i][n-1-j];21 matrix[n-1-i][n-1-j] = matrix[n-1-(n-1-j)][n-1-i];22 matrix[n-1-(n-1-j)][n-1-i] =temp;23 }24 }25 }

我的复杂度:O(N2)

编码过程中的问题:

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

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

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

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

答案代码:

1 public void rotate(int[][] matrix) {2 int n =matrix.length;3 if (n <= 1) {4 return;5 }6

7 int x = (n-1)/2;8 for (int i = 0; i <= x; i++) {9 int[] tmp =matrix[i];10 matrix[i] = matrix[n-1-i];11 matrix[n-1-i] =tmp;12 }13

14 for (int i = 0; i < n; i++) {15 for (int j = i+1; j < n; j++) {16 int temp =matrix[i][j];17 matrix[i][j] =matrix[j][i];18 matrix[j][i] =temp;19 }20 }21 }

答案复杂度: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:把第一步的上下对称交换改成左右对称交换,第二步不变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值