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

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


文章目录

  • 矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码
    • @[TOC](文章目录)
  • 题目
  • 一、审题
  • zigzag扫描打印矩阵的宏观调度
  • 手撕zigzag扫描打印矩阵的代码
  • 错误的Ar和Bc的更新顺序
  • 总结

题目

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


一、审题

示例:
matrix=
1 2 3 4
5 6 7 8
9 10 11 12

打印顺序是这样的
1 2 5 9 6 3 4 7 10 11 8 12

由于空间逻辑上扫描打印的轨迹酷似Z形状,故叫zigzag扫描打印。


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的横纵坐标绝对不能同时变,否则就是斜着走!!!

(2)上面(1)宏观调度的每一步,每一个AB点的连线,都要连续打印很多数,直接定义一个函数打印
abPrint(Ar,Ac,Br,Bc,fromAB)
要么是从A–B打印,要么是从B–A打印,2种状态,就用Boolean值标记吧
不妨设A–B打印的标志fromAB=true。
显然,一开始是从B–A,所以取fromAB=false

行,咱们先手撕打印函数的代码,给定AB坐标,和fromAB的标记,咱们顺溜打印一条线

如果是从A–B打印,那顺溜的就是Ac–,Ar++,这样从A点挪到B点打印完事之后就停止
如果是从B–A打印,那顺溜的就是Bc++,Br–,这样从B点挪到A点打印完事之后就停止

打印的代码如下:

    //复习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扫描打印矩阵的代码

上面说的Ar的更新放在前面,Bc的更新一定放前面,要记住了
你不信自己调试代码看,是错的,斜着走,打印就会少了很多数据

咱们手撕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,15zigzagPrintMatrix(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,15zigzagPrintMatrix(arr);System.out.println();zigzagPrintMatrixReview(arr);System.out.println();wrongZigzagPrintMatrixReview(arr);}public static void main(String[] args) {test();}

由于Ac先更新,到右边界M-1,引发Ar+1,所以A斜着走了
由于Br先更新,到下边界N-1,引发Bc+1,所以B也斜着走了
导致矩阵很多地方没有被打印:

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的更新放前面,就能避免这个错误!


总结

提示:重要经验:

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

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

  1. [剑指offer]顺时针打印矩阵

    [剑指offer]顺时针打印矩阵 剑指offer-顺时针打印矩阵 题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4, ...

  2. java 打印_剑指Offer面试题20(Java版):顺时针打印矩阵

    题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字.例如:如果输入如下矩阵: 1,2,3,4 5,6,7,8 9,10,11,12 13,14,15,16 则依次打印出数字1,2,3, ...

  3. 剑指offer:顺时针打印矩阵(java)

    题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字.例如:如果输入如下矩阵: 1,2,3,4 5,6,7,8 9,10,11,12 13,14,15,16 则依次打印出数字1,2,3, ...

  4. 矩阵打印问题-zigzag打印矩阵

    矩阵打印技巧:找到矩阵宏规律1,不要陷入细节, zigzag打印矩阵 宏观的规律是什么 ? 其实比较宏观的规律是都是打印斜线,只是方向不同而已(这个问题很容易解决): 如何实现宏观的规律? 使用A[a ...

  5. 【STM32扫描4x4矩阵键盘模块】 4x4 matrix keypad interface

    [STM32扫描4x4矩阵键盘模块] 4x4 matrix keypad interface 4x4矩阵键盘模块 矩阵键盘是将多个按键排布成类似矩阵形式的键盘组.为了减少IO资源的占用,将键盘组的每一 ...

  6. 面试题29. 顺时针打印矩阵

    Title 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7, ...

  7. 笔试算法题(26):顺时针打印矩阵 求数组中数对差的最大值

    出题: 输入一个数字矩阵,要求从外向里顺时针打印每一个数字: 分析: 从外向里打印矩阵有多重方法实现,但最重要的是构建合适的状态机,这样才能控制多重不同的操作: 注意有四种打印模式(左右,上下,右左, ...

  8. 矩阵打印技巧-转圈打印矩阵

    转圈打印矩阵 矩阵的宏观规律是什么? 1.根据方向首先打印,打印最外层,然后在打印内层 2.在对打印每一层进行拆解 1.首先打印一层的函数: 切记要处理边界条件,只有一行和只有一列的矩阵 //A为起始 ...

  9. 剑指offer:面试题29. 顺时针打印矩阵

    题目:顺时针打印矩阵 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9 ...

最新文章

  1. Redis的一些“锁”事
  2. python获取图片像素矩阵_用python处理图片实现图像中的像素访问
  3. Nginx-09:Nginx原理
  4. 毕业论文选题三步搞定!
  5. ASP.NET MVC中如何实现页面跳转
  6. Xcode做简易计算器
  7. .net 读取mysql数据库配置文件_.NETCore添加及读取默认配置文件信息
  8. Linux学习之shell
  9. pytorch按照索引取batch中的数
  10. POJ2536 Gopher II【二分图最大匹配】
  11. xml与实体互相转换
  12. 数字电路逻辑设计之逻辑函数
  13. cad快捷栏怎么调出来_cad怎么显示工具栏快捷键 cad快捷键常见问题解决办法
  14. vue---获取元素额外生成的data-v-xxx
  15. GreenDao的简单学习(附带demo源码)
  16. 腾讯成立“XR”部门押注元宇宙;iPhone14全系售价上涨;新东方5 万高薪聘请双语主播 |聚观早报
  17. SQL笔试:Student学生表,Course 课程表,Sc选课表
  18. 学术圈很火的 超材料、超表面、超透镜:什么时候可以代替传统透镜?
  19. scratch-blocks教程(一)
  20. Docker入门实战大全终极版

热门文章

  1. 一元多项式加减乘实现c/c++
  2. 计算机网络 思科模拟器进行交换机端口隔离,跨交换机实现vlan实验
  3. 基于C语言设计的小型图形软件系统
  4. loopback地址是什么?怎么配置
  5. 什么是c语言系统调用,什么是系统调用?为什么要用系统调用?
  6. 怎样用一台手机做自媒体?
  7. 大漠老师:2022 年的 CSS,到底有哪些特性
  8. 浅论信息流广告与DSP营销推广的区别有哪些
  9. 光电耦合器的工作原理以及应用
  10. nRF52832低功耗蓝牙应用开发之入门教程