矩阵宏观调度: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
