矩阵宏观调度:将正方形矩阵原地顺时针旋转90°度
提示:极其重要的矩阵处理技巧,矩阵下标的宏观调度
重要的矩阵的宏观调度基础知识:
【1】矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码
【2】矩阵宏观调度:沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印
题目
矩阵宏观调度:将正方形矩阵原地顺时针旋转90°度
一、审题
示例:
arr=
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
沿着下面矩阵中心+顺时针旋转90°,变成
矩阵宏观调度,外圈向内圈,一批一批旋转,替代
单看外圈,下图绿点
定义一个循环旋转函数circleRotate(a,b,c,d):
ab=00,cd=N-1,M-1确定了这外圈
(1)让tmp记录橘色这段
(2)让粉色段过来替代橘色段
(3)让红色段过来替代粉色段
(4)让蓝色段过来替换红色段
(5)让tmp替代蓝色段
岂不就完成了顺时针旋转90°?
简单吧
跟
【2】矩阵宏观调度:沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印
一样,若是此刻,将ab++,cd–,就进入内圈,继续调用(1)循环旋转
这样整体就旋转完成了
切记a<c,b<d,如果a=c,b=d那就是一个点
一个点不用旋转了,下图5数字,外圈转完,ab++,cd–,a=c,b=d就一个数,怎么旋转还是它!
我们来看细节:
循环旋转函数circleRotate(a,b,c,d):
ab=00,cd=N-1,M-1确定了这外圈
其实每一批,旋转多少个数呢?d-b个数,比如下面d=3,b=0,d-b=3个
下标就是0 1 2 就0–d-b-1
所以替代的话,咱们下标从i=0–d-b-1,一个一个替换,跟交换函数一样
手撕代码如下:
//复习旋转
//循环旋转函数**circleRotate(a,b,c,d):**
public static void circleRotate(int[][] arr, int a, int b, int c, int d){
//ab,cd=确定了这外圈
//其实每一批,旋转多少个数呢?d-b个数,比如下面d=3,b=0,d-b=3个
for (int i = 0; i < d - b; i++) {
//下标就是0 1 2 就0--d-b-1
//所以替代的话,咱们下标从i=0--d-b-1,一个一个替换,跟交换函数一样
int tmp = arr[a][b + i];//记忆橘色这一行,从左往右
arr[a][b + i] = arr[c - i][b];//搬粉色b那列,c从下往上
arr[c - i][b] = arr[c][d - i];//搬红色c那行,d从右往左
arr[c][d - i] = arr[a + i][d];//搬蓝色d那列,a从上往下
arr[a + i][d] = tmp;//搬记忆的橘色a这一行,b从左往右
}
//最重要的就是下标控制,走向
}
整个矩阵的调度:
最开始ab=00,cd=N-1,M-1确定了这外圈,外圈旋转完,将ab++,cd–,就进入内圈,继续调用circleRotate函数循环旋转
//最开始ab=00,cd=N-1,M-1确定了这外圈,外圈旋转完,
// 将ab++,cd--,就进入内圈,继续调用circleRotate函数循环旋转
public static void rotateMatrixReview(int[][] arr){
if (arr == null || arr.length == 0 || arr[0].length == 0) return;
int a = 0;
int b = 0;
int c = arr.length - 1;
int d = arr[0].length - 1;
while (a < c) circleRotate(arr, a++, b++, c--, d--);
}
public static void test(){
int[][] arr = {
{1, 2, 3, 4},
{6, 7, 8, 9},
{11,12,13,14},
{16,17,18,19}
};
int[][] arr2 = {
{1, 2, 3, 4},
{6, 7, 8, 9},
{11,12,13,14},
{16,17,18,19}
};
//旋转完以后
// {16, 11, 6, 1},
// {17, 12, 7, 2},
// {18, 13, 8, 3},
// {19, 14, 9, 4}
rotateMatrixPrint(arr);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
System.out.print(arr[i][j] +" ");
}
System.out.println();
}
System.out.println();
rotateMatrixReview(arr2);
for (int i = 0; i < arr2.length; i++) {
for (int j = 0; j < arr2[0].length; j++) {
System.out.print(arr2[i][j] +" ");
}
System.out.println();
}
}
public static void main(String[] args) {
test();
}
测试一把:
16 11 6 1
17 12 7 2
18 13 8 3
19 14 9 4
16 11 6 1
17 12 7 2
18 13 8 3
19 14 9 4
总结
提示:重要经验:
1)矩阵的宏观调度,非常有趣,按照AB点同步走,或者abcd固定外圈,一批一批数据调度完,往内继续循环调度
2)本题的关键,就在先tmp记录一批数据,拿另一批数据旋转过来覆盖,abcd固定不动,从一个方向到一个方向一个个搬移,下标要搞清楚
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。