• 矩阵问题(宏观调度)



    题目一

    给定一个正方形矩阵matrix,原地调整成顺时针90度转动的样子

    a  b  c			g  d  a
    d  e  f			h  e  b
    g  h  i			i  f  c
    
    • 1
    • 2
    • 3

    解题思路

    从外往里更新,每一圈都旋转90°
    在这里插入图片描述
    如图,先更新第一层,再更新第二层,最后更新最里面一层
    在这里插入图片描述

    代码

    	public static void rotate(int[][] matrix) {
    		int a = 0;
    		int b = 0;
    		int c = matrix.length - 1;
    		int d = matrix[0].length - 1;
    		while (a < c) {
    			rotateEdge(matrix, a++, b++, c--, d--);
    		}
    	}
    
    	public static void rotateEdge(int[][] m, int a, int b, int c, int d) {
    		int tmp = 0;
    		for (int i = 0; i < d - b; i++) {
    			tmp = m[a][b + i];
    			m[a][b + i] = m[c - i][b];
    			m[c - i][b] = m[c][d - i];
    			m[c][d - i] = m[a + i][d];
    			m[a + i][d] = tmp;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    一、题目二

    给定一个长方形矩阵matrix,实现转圈打印

    a  b  c  d
    e  f  g  h
    i  j  k  L
    
    • 1
    • 2
    • 3

    打印顺序:a b c d h L k j i e f g
    在这里插入图片描述

    解题思路

    分圈结构
    先想在这一个框里怎么实现打印。结果你会发现下一个框的第一个正好跟上一个框的最后一个结上了。
    也就是说你只用解决在一个框里这样打印就行了。下一个框在这么打印,它每一个第一个都会跟前一个最后一个接上。
    在这里插入图片描述
    在这里插入图片描述
    每一层中,从m[a][b]到m[a][d],再从m[a+1][d]到m[c][d],再从m[c][d-1]到m[c][b],再从m[c+1][b]到m[a-1][b]

    代码

    class Solution {
        List<Integer> res=new ArrayList<>();
        public List<Integer> spiralOrder(int[][] matrix) {
           int tR = 0;
    		int tC = 0;
    		int dR = matrix.length - 1;
    		int dC = matrix[0].length - 1;
            while (tR <= dR && tC <= dC) {
    			process(matrix, tR++, tC++, dR--, dC--);
    		}
            return res;
        }
        public void process(int[][] m,int tR,int tC,int dR,int dC){
          if (tR == dR) {
    			for (int i = tC; i <= dC; i++) {
    				res.add(m[tR][i]);
    			}
    		} else if (tC == dC) {
    			for (int i = tR; i <= dR; i++) {
    				res.add(m[i][tC]);
    			}
    		} else {
    			int curC = tC;
    			int curR = tR;
    			while (curC != dC) {
    				res.add(m[tR][curC]);
    				curC++;
    			}
    			while (curR != dR) {
    				res.add(m[curR][dC]);
    				curR++;
    			}
    			while (curC != tC) {
    				res.add(m[dR][curC]);
    				curC--;
    			}
    			while (curR != tR) {
    				res.add(m[curR][tC]);
    				curR--;
    			}
    		}
           
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    问题三

    给定一个正方形或者长方形矩阵matrix,实现zigzag打印
    0 1 2
    3 4 5
    6 7 8
    打印: 0 1 3 6 4 2 5 7 8
    在这里插入图片描述

    解题思路

    你要是把眼光盯在局部位置怎么变上你被玩死了。你要是想描述单独每一个点到来的下标,用这种特别局部的思想去考虑这个题,你完蛋了。我们刚才说的分圆结构其实是一种拔出局部想法之外的一种,让你刻意的去找宏观感的一种东西。

    在这里插入图片描述
    所以给你带来的想法就是你怎么样跳出局部
    一且遇到这种类似矩阵调整的问题和打印的问题,就设计宏观过程。有一个A点,它一开始来自于左上角,有1个B点,它也来自于左上角,我规定了A先往右。走到不能再右了再往下。我规定B先往下走,走到不能再下了,再往右。A,B运动过程中它俩会压中一条直直的斜线,每次斜线的方向是相反的,搞出来了。你只要写一个简单函数给你一条直直的斜线,要么往上方打印,要么往下方打印,接下来AB一起走路,这事解决了。

    代码

    	public static void printMatrixZigZag(int[][] matrix) {
    		int tR = 0;
    		int tC = 0;
    		int dR = 0;
    		int dC = 0;
    		int endR = matrix.length - 1;
    		int endC = matrix[0].length - 1;
    		boolean fromUp = false;
    		while (tR != endR + 1) {
    			printLevel(matrix, tR, tC, dR, dC, fromUp);
    			tR = tC == endC ? tR + 1 : tR;
    			tC = tC == endC ? tC : tC + 1;
    			dC = dR == endR ? dC + 1 : dC;
    			dR = dR == endR ? dR : dR + 1;
    			fromUp = !fromUp;
    		}
    		System.out.println();
    	}
    
    	public static void printLevel(int[][] m, int tR, int tC, int dR, int dC, boolean f) {
    		if (f) {
    			while (tR != dR + 1) {
    				System.out.print(m[tR++][tC--] + " ");
    			}
    		} else {
    			while (dR != tR - 1) {
    				System.out.print(m[dR--][dC++] + " ");
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    Vue+Element之SpingBoot学生管理系统
    Vue2+ElementUI 静态首页案例
    ruoyi-plus创建模块、自动生成代码
    什么是DNS缓存?DNS缓存有哪些作用?
    架构师日记-33个常见编码漏洞大揭秘
    远程小组软件开发过程(3):人
    国产化系统中遇到的视频花屏、卡顿以及延迟问题的记录与总结
    虚拟网络适配器的实现
    专为大模型训练优化,百度集合通信库 BCCL 万卡集群快速定位故障
    Python:魔术方法(__getitem__、__len__等包含双下划线构成的方法)的简介、使用案例之详细攻略
  • 原文地址:https://blog.csdn.net/xiaolu567/article/details/125441097