矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码

矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码1 矩阵的 zigzag 扫描打印是图像工程中的一种编码方式 它的扫描打印代码是需要利用宏观调度的 2 AB 从左上角 A 先往右 B 先往下 然后 A 往下 B 往右 最后相遇结束 尤其要注意 Ar 更新和 Bc 的更新 一定要放在 Ac 和 Br 的前面 3 笔试求 AC 可以不考虑空间复杂度 但是面试既要考虑时间复杂度最优 也要考虑空间复杂度最优

矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码

提示:极其重要的矩阵处理技巧,矩阵下标的宏观调度


题目

给你一个矩阵,请你用Zigzag扫描打印矩阵matrix


一、审题


zigzag扫描打印矩阵的宏观调度

在这里插入图片描述
记住这种宏观调度策略,矩阵N行M列
(1)令AB最开始都在0 0原点【Ar=Br=0 && Ac=Bc=0】
r是row代表行下标,c是column代表列下标
宏观思想就是AB同步走,A先往右,同时B往下走
A到右边界M,转头往下走
B到下边界N,转头往右走
等啥时候AB再相遇【Ar=Br=N-1 && Ac=Bc=M-1】,结束扫描
在这里插入图片描述
上图中,
最开始A的列Ac,Ac还没有到右边界M-1,则可以先往右增加,此时Ar不能变动,
如果Ac=M-1,到右边界了,Ar才可以开始增加,A往下走,所以Ar的判断条件和走法是图中第三行的情况。
类似的,
最开始B的行Br,Br还没有到下边界N-1,则可以先往下增加,此时Bc不能变动,
如果Br=N-1,到下边界了,Bc才可以开始增加,B往右走,所以Bc的判断条件和走法时图中的第四行的情况。
看明白了这个宏观调度了吧!






























实际操作的时候要小心!!!
实际操作的时候要小心!!!
实际操作的时候要小心!!!





在这里插入图片描述

由于Ac变化在前,Ac会影响Ar,所以把Ar的更新放在前面,否则容易导致Ar提前变大
同样由于Br的变化在前,Br会影响Bc的更新,所以把Bc的更新放在前面,否则容易导致Bc提前变大

 Ar = Ac == M - 1 ? Ar + 1: Ar;//这句得放前面 Ac = Ac == M - 1 ? Ac : Ac + 1;//Ac到右边界不能动 Bc = Br == N - 1 ? Bc + 1: Bc;//这句话得放前面!!! Br = Br == N - 1 ? Br : Br + 1;//到下边界就停 

你不信把代码调换试试,

 Ac = Ac == M - 1 ? Ac : Ac + 1;//Ac到右边界不能动 Ar = Ac == M - 1 ? Ar + 1: Ar;//这句得放前面 Br = Br == N - 1 ? Br : Br + 1;//到下边界就停 Bc = Br == N - 1 ? Bc + 1: Bc;//这句话得放前面!!! 

中途,由于Ac抵达M-1,Ar里面就得到了Ac == M – 1满足的条件,就会触发Ar=Ar + 1,
相当于Ac和Ar同时+1,你就不是A水平走了,而是斜着走,这是错的
我们要求A水平走,再垂直走,要求B先垂直走,再水平走
AB的横纵坐标绝对不能同时变,否则就是斜着走!!!






打印的代码如下:

 //复习zigzag扫描打印 //从A--B,或者B--A一条线顺溜的打印 public static void abPrint(int[][] arr, int Ar, int Ac, int Br, int Bc, boolean fromAB){ 
       //一进来如果A=B点,打印一个即可 if (Ar == Br && Ac == Bc) System.out.print(arr[Ar][Ac] +" "); //从A--B一条线顺溜的打印 while (fromAB && Ar != Br){ 
       //只要A还没有与B相遇则打印一溜 System.out.print(arr[Ar][Ac] +" "); Ar++; Ac--;//从右上角A往左下角B滑动 } //从B--A一条线顺溜的打印 while (!fromAB && Br != Ar){ 
       //只要B还没有与A相遇则打印一溜 System.out.print(arr[Br][Bc] +" "); Br--; Bc++;//从左下角B往右上角A滑动 } } 

手撕zigzag扫描打印矩阵的代码

咱们手撕zigzag扫描打印矩阵的代码如下:

 //zigzag扫描打印矩阵的宏观调度 public static void zigzagPrintMatrixReview(int[][] arr){ 
        if (arr == null || arr.length == 0) return; int N = arr.length; int M = arr[0].length;//边界 //(1)令AB最开始都在0 0原点【Ar=Br=0 && Ac=Bc=0】 //宏观思想就是AB同步走,A先往右,同时B往下走 //A到右边界M,转头往下走 //B到下边界N,转头往右走 //等啥时候AB再相遇【Ar=Br=N-1 && Ac=Bc=M-1】,结束扫描 int Ar = 0; int Br = 0; int Ac = 0; int Bc = 0; boolean fromAB = false;//开始是B--A一溜打印 while (Ar < N){ 
        //(2)上面(1)宏观调度的每一步,每一个AB点的连线,都要连续打印很多数 abPrint(arr, Ar, Ac, Br, Bc, fromAB); //打印完A--B,或者B--A就要调度AB同步走 //最开始A的列Ac,Ac还没有到右边界M-1,则可以先往右增加,此时Ar不能变动, //如果Ac=M-1,到右边界了,Ar才可以开始增加,A往下走,所以Ar的判断条件和走法是图中第三行的情况。 Ar = Ac == M - 1 ? Ar + 1: Ar;//这句得放前面 Ac = Ac == M - 1 ? Ac : Ac + 1;//Ac到右边界不能动 //类似的, //最开始B的行Br,Br还没有到下边界N-1,则可以先往下增加,此时Bc不能变动, //如果Br=N-1,到下边界了,Bc才可以开始增加,B往右走,所以Bc的判断条件和走法时图中的第四行的情况。 Bc = Br == N - 1 ? Bc + 1: Bc;//这句话得放前面!!! Br = Br == N - 1 ? Br : Br + 1;//到下边界就停 //掉头扫描 fromAB = !fromAB; } //当AB相遇,下一次Ar就会越界的 } public static void test(){ 
        int[][] arr = { 
        { 
       1, 2, 3, 4, 5}, { 
       6, 7, 8, 9, 10}, { 
       11, 12, 13, 14,15} };//打印1,2,6,11,7,3,4,8,12,13,9,5,10,14,15 zigzagPrintMatrix(arr); System.out.println(); zigzagPrintMatrixReview(arr); } public static void main(String[] args) { 
        test(); } 

结果如下:

1 2 6 11 7 3 4 8 12 13 9 5 10 14 15 1 2 6 11 7 3 4 8 12 13 9 5 10 14 15 

错误的Ar和Bc的更新顺序

把代码调换试试,

 Ac = Ac == M - 1 ? Ac : Ac + 1;//Ac到右边界不能动 Ar = Ac == M - 1 ? Ar + 1: Ar;//这句得放前面 Br = Br == N - 1 ? Br : Br + 1;//到下边界就停 Bc = Br == N - 1 ? Bc + 1: Bc;//这句话得放前面!!! 

整体如下:

 //错误的zigzag扫描打印矩阵的宏观调度 public static void wrongZigzagPrintMatrixReview(int[][] arr){ 
         if (arr == null || arr.length == 0) return; int N = arr.length; int M = arr[0].length;//边界 //(1)令AB最开始都在0 0原点【Ar=Br=0 && Ac=Bc=0】 //宏观思想就是AB同步走,A先往右,同时B往下走 //A到右边界M,转头往下走 //B到下边界N,转头往右走 //等啥时候AB再相遇【Ar=Br=N-1 && Ac=Bc=M-1】,结束扫描 int Ar = 0; int Br = 0; int Ac = 0; int Bc = 0; boolean fromAB = false;//开始是B--A一溜打印 while (Ar < N){ 
         //(2)上面(1)宏观调度的每一步,每一个AB点的连线,都要连续打印很多数 abPrint(arr, Ar, Ac, Br, Bc, fromAB); //打印完A--B,或者B--A就要调度AB同步走 //最开始A的列Ac,Ac还没有到右边界M-1,则可以先往右增加,此时Ar不能变动, //如果Ac=M-1,到右边界了,Ar才可以开始增加,A往下走,所以Ar的判断条件和走法是图中第三行的情况。 Ac = Ac == M - 1 ? Ac : Ac + 1;//Ac到右边界不能动 Ar = Ac == M - 1 ? Ar + 1: Ar;//这句得放前面 //类似的, //最开始B的行Br,Br还没有到下边界N-1,则可以先往下增加,此时Bc不能变动, //如果Br=N-1,到下边界了,Bc才可以开始增加,B往右走,所以Bc的判断条件和走法时图中的第四行的情况。 Br = Br == N - 1 ? Br : Br + 1;//到下边界就停 Bc = Br == N - 1 ? Bc + 1: Bc;//这句话得放前面!!! //掉头扫描 fromAB = !fromAB; } //当AB相遇,下一次Ar就会越界的 } public static void test(){ 
         int[][] arr = { 
         { 
        1, 2, 3, 4, 5}, { 
        6, 7, 8, 9, 10}, { 
        11, 12, 13, 14,15} };//打印1,2,6,11,7,3,4,8,12,13,9,5,10,14,15 zigzagPrintMatrix(arr); System.out.println(); zigzagPrintMatrixReview(arr); System.out.println(); wrongZigzagPrintMatrixReview(arr); } public static void main(String[] args) { 
         test(); } 
1 2 6 11 7 3 4 8 12 13 9 5 10 14 15 1 2 6 11 7 3 4 8 12 13 9 5 10 14 15 1 2 6 12 4 14 10 15 

因此,一定记住了,把Ar的更新放在前面,把Bc的更新放前面,就能避免这个错误!


总结

提示:重要经验:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/217797.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午8:44
下一篇 2026年3月18日 上午8:45


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号