旋转图像
一、题目简介
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
(题目来源:力扣(LeetCode))
示例 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]
]
二、解决方法
1. 使用另一个矩阵(题目要求不这么做,我们就首先这样做,在做的过程中获取经验)
class Solution {
public static void rotate(int[][] matrix) {
//辅助矩阵
int matrixR[][]=new int[matrix.length][matrix.length];
//循环赋值
for (int i = 0; i < matrixR.length; i++) {
for (int j = 0; j < matrixR.length; j++) {
matrixR[j][matrixR.length-i-1]=matrix[i][j];
}
}
//将原数组替换,因为力扣不让返回,那只好改变原数组了
for (int i = 0; i < matrixR.length; i++) {
matrix[i]=matrixR[i];
}
}
}
2. 循环移动
44的矩阵:
我们可以看成两个正方形,最外面的那个44的正方形,和里面的那个2*2的正方形
首先移动顺时针移动大正方形
- 复制数组[1,2,3,4]保留
- 将第一行替换为1,5,9,12
1 2 3 4 1 5 9 12
5 6 7 8 ===》 5 6 7 8
9 10 11 12 9 10 11 12
12 14 15 16 12 14 15 16
- 将第一列替换为12,14,15,16
1 2 3 4 12 5 9 12
5 6 7 8 ===》 14 6 7 8
9 10 11 12 15 10 11 12
12 14 15 16 16 14 15 16
- 第四行替换为16,12,8,4
1 2 3 4 12 5 9 12
5 6 7 8 ===》 14 6 7 8
9 10 11 12 15 10 11 12
12 14 15 16 16 12 8 4
- 将复制的数组替换到第四列
1 2 3 4 12 5 9 1
5 6 7 8 ===》 14 6 7 2
9 10 11 12 15 10 11 3
12 14 15 16 16 12 8 4
第一个正方形旋转完毕,第二个正方形同理
代码:
package com.lxf.test;
import java.util.Arrays;
public class Rotate {
public static void main(String[] args) {
int[][] arr=new int[][]{
{
5, 1, 9,11,17,18},
{
2, 4, 8,10,19,20},
{
13, 3, 6, 7,21,22},
{
15,14,12,16,23,24},
{
25,26,27,28,29,30},
{
31,32,33,34,35,36}
};
rotate(arr);
for (int[] nums : arr) {
for (int num : nums) {
System.out.print(num+" ");
}
System.out.println();
}
}
public static void rotate(int[][] matrix) {
int length=matrix.length;
for (int i = 0, j=length-1; i < length; i++,j--) {
//结束条件
if(i>=j){
break;
}
//记录第i个正方形的第一条边
int[] records = Arrays.copyOfRange(matrix[i], i,j+1);
//移动第四条边到第一条边
int k=j;
while(k>=i){
matrix[i][k]=matrix[length-1-k][i];
k--;
}
//移动第三条边到第四条边
int m=i;
while(m<=j){
matrix[m][i]=matrix[j][m];
m++;
}
//移动第二条边到第三条边
int n=j;
while(n>=i){
matrix[j][length-1-n]=matrix[n][j];
n--;
}
//将第一条边移动到第二条边
int p=i;
int q=0;
while (p<=j){
matrix[p][j]=records[q++];
p++;
}
}
}
}
代码优化:
package com.lxf.test;
import java.util.Arrays;
public class Rotate {
public static void main(String[] args) {
int[][] arr=new int[][]{
{
5, 1, 9,11,17,18},
{
2, 4, 8,10,19,20},
{
13, 3, 6, 7,21,22},
{
15,14,12,16,23,24},
{
25,26,27,28,29,30},
{
31,32,33,34,35,36}
};
rotate(arr);
for (int[] nums : arr) {
for (int num : nums) {
System.out.print(num+" ");
}
System.out.println();
}
// 15,13,2,5
// 14,3,4,1
// 12,6,8,9
// 16,7,10,11
}
public static void rotate(int[][] matrix) {
int length=matrix.length;
for (int i = 0, j=length-1; i < length; i++,j--) {
//中止条件
if(i>=j){
break;
}
//记录正方形第一行
int[] records = Arrays.copyOfRange(matrix[i], i,j+1);
int k=j;
int one=matrix[j][i];
while(k>=i){
matrix[i][k]=matrix[length-1-k][i];
matrix[length-k-1][i]=matrix[j][length-k-1];
matrix[j][length-1-k]=matrix[k][j];
k--;
}
//遍历数组
int p=i;
int q=0;
while (p<=j){
matrix[p][j]=records[q++];
p++;
}
//注意:每一次都有一个错误,就是顶点交换时matrix[i][i]是最后一次赋值
//可是它原本值matrix[i][j]在第一波就被赋值了。最后再次处理:
matrix[i][i]=one;
//还有就是第一波matrix[j][j]被赋值数组最后一个值会引起matrix[0][j]最后一次赋值时错误
//但是我们是顺序遍历数组,列增加所以避免了这个错误
}
}
}
- 更多题解:链接