内容:
1、转圈打印矩阵问题
2、旋转正方形矩阵问题
3、之字形打印矩阵问题
4、在行和列都排序好的矩阵中找数
1、转圈打印矩阵问题
问题描述:
1 给定一个整形矩阵matrix,请按照转圈的方式打印它。 2 3 例如: 4 1 2 3 4 5 5 6 7 8 6 9 10 11 12 7 13 14 15 16 8 9 打印结果为: 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 10 要求额外空间复杂度为O(1)
解决思路:
一圈一圈的打印,比如上面的1到16到1为1圈,6到11到6为1圈,主要就是要注意边界问题
代码:
1 public class RotateOutputMatrix { 2 private int M; 3 private int N; 4 private int[][] arr; 5 private final int startValue = 1; 6 7 // 初始化矩阵 8 public RotateOutputMatrix(int M, int N) { 9 this.M = M; 10 this.N = N; 11 int value = startValue; 12 arr = new int[M][N]; 13 for (int i = 0; i < M; i++) { 14 for (int j = 0; j < N; j++) { 15 this.arr[i][j] = value++; 16 } 17 } 18 } 19 20 public void printEdge(int a, int b, int c, int d) { 21 // 输出一层 22 // (a, b) -> 左上角 (c, d) -> 右下角 23 if (b == d) { 24 // 两个点在一列上 25 for (int i = a; i <= c; i++) { 26 System.out.print(arr[i][b] + " "); 27 } 28 } else if (a == c) { 29 // 两个点在一行上 30 for (int j = b; j <= d; j++) { 31 System.out.print(arr[a][j] + " "); 32 } 33 } else { 34 // 两个点不在一行也不在一列上 -> 两个点在对角线上 35 int curA = a; 36 int curB = b; 37 while (curB < d) { 38 System.out.print(arr[curA][curB] + " "); 39 curB++; 40 } 41 while (curA < c) { 42 System.out.print(arr[curA][curB] + " "); 43 curA++; 44 } 45 while (curB > b) { 46 System.out.print(arr[curA][curB] + " "); 47 curB--; 48 } 49 while (curA > a) { 50 System.out.print(arr[curA][curB] + " "); 51 curA--; 52 } 53 } 54 } 55 56 public void printAllEdge() { 57 // 输出所有的层 58 int a = 0; 59 int b = 0; 60 int c = this.M - 1; 61 int d = this.N - 1; 62 while (a <= c && b <= d) { 63 printEdge(a++, b++, c--, d--); 64 } 65 } 66 67 // test 68 public void printMartix(){ 69 for(int i=0; i<arr.length; i++){ 70 for(int j=0; j<arr[0].length; j++){ 71 System.out.print(arr[i][j] + " "); 72 } 73 System.out.println(); 74 } 75 } 76 77 public static void main(String[] args) { 78 RotateOutputMatrix test = new RotateOutputMatrix(4, 4); 79 test.printMartix(); 80 System.out.println("================="); 81 test.printAllEdge(); 82 } 83 }
2、旋转正方形矩阵问题
问题描述:
给定一个整型正方形矩阵matrix,请把该矩阵调整成 顺时针旋转90度的样子
思路:
和上面那道题类似,一层一层的转,每一层中又可以分成若干旋转次数进行转(旋转次数=边上的元素个数-1)
比如:
1 2 3
4 5 6
7 8 9
最外层是1 2 3 6 9 8 7 4 可以先转1 3 9 7 再转 2 6 8 4
代码:
1 public class RotateSquare90 { 2 private int M; 3 private int[][] arr; 4 private final int startValue = 1; 5 6 public RotateSquare90(int M) { 7 this.M = M; 8 int value = startValue; 9 arr = new int[M][M]; 10 for (int i = 0; i < M; i++) { 11 for (int j = 0; j < M; j++) { 12 this.arr[i][j] = value++; 13 } 14 } 15 } 16 17 public void rotateEdge(int a, int b, int c, int d) { 18 // 旋转一层 19 int times = c - a; 20 int tmp = 0; 21 for (int i = 0; i < times; i++) { 22 tmp = arr[a][b + i]; 23 arr[a][b + i] = arr[c - i][b]; 24 arr[c - i][b] = arr[c][d - i]; 25 arr[c][d - i] = arr[a + i][d]; 26 arr[a + i][d] = tmp; 27 } 28 } 29 30 public void rotateAllEdge() { 31 // 旋转所有层 32 int i = 0; 33 int j = 0; 34 int m = this.M - 1; 35 int n = this.M - 1; 36 while(i<=m&&j<=n){ 37 rotateEdge(i++, j++, m--, n--); 38 } 39 } 40 41 // for test 42 public void printMatrix() { 43 int[][] m = this.arr; 44 for (int i = 0; i < m.length; i++) { 45 for (int j = 0; j < m[0].length; j++) { 46 System.out.print(m[i][j] + " "); 47 } 48 System.out.println(); 49 } 50 } 51 52 public static void main(String[] args) { 53 RotateSquare90 test = new RotateSquare90(4); 54 test.printMatrix(); 55 test.rotateAllEdge(); 56 test.printMatrix(); 57 } 58 59 }
3、之字形打印矩阵问题
问题描述:
给定一个矩阵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
要求额外空间复杂度为O(1)
思路:
同样还是分层,左下到右上为1层,用一个布尔值表示是从上到下还是从下到上,然后最外层控制从开始到结束
代码:
1 public class ZigZagPrintMatrix { 2 private int M; 3 private int N; 4 private int[][] arr; 5 private final int startValue = 1; 6 7 public ZigZagPrintMatrix(int M, int N) { 8 this.M = M; 9 this.N = N; 10 int value = startValue; 11 arr = new int[M][N]; 12 for (int i = 0; i < M; i++) { 13 for (int j = 0; j < N; j++) { 14 this.arr[i][j] = value++; 15 } 16 } 17 } 18 19 public void printLevel(int a, int b, int c, int d, boolean f) { 20 // 打印一条斜线 f为true表示从右上到左下打印 21 if (f) { 22 // (a, b) -> (c, d) 23 while (a != c + 1) { 24 System.out.print(arr[a++][b--] + " "); 25 } 26 } else { 27 // (c, d) -> (a, b) 28 while (d != b + 1) { 29 System.out.print(arr[c--][d++] + " "); 30 } 31 } 32 } 33 34 public void printMatrixZigZag() { 35 // 打印所有斜线 36 int a = 0; 37 int b = 0; 38 int c = 0; 39 int d = 0; 40 int endR = M - 1; 41 int endC = N - 1; 42 boolean fromUp = false; 43 while (a != endR + 1) { 44 printLevel(a, b, c, d, fromUp); 45 a = b == endC ? a + 1 : a; 46 b = b == endC ? b : b + 1; 47 d = c == endR ? d + 1 : d; 48 c = c == endR ? c : c + 1; 49 fromUp = !fromUp; 50 } 51 System.out.println(); 52 } 53 54 // test 55 public void printMartix() { 56 for (int i = 0; i < arr.length; i++) { 57 for (int j = 0; j < arr[0].length; j++) { 58 System.out.print(arr[i][j] + " "); 59 } 60 System.out.println(); 61 } 62 } 63 64 public static void main(String[] args) { 65 ZigZagPrintMatrix test = new ZigZagPrintMatrix(3, 4); 66 test.printMartix(); 67 test.printMatrixZigZag(); 68 } 69 }
4、在行和列都排序好的矩阵中找数
问题描述:
1 给定一个N×M的整型矩阵matrix和一个正数K,matrix的每一行每一列都是排好序的。实现一个函数,判断K是否在matrix中 2 例如: 3 0, 1, 2, 5 4 2, 3, 4, 7 5 4, 4, 4, 8 6 5, 7, 7, 9 7 如果K为7,返回True;如果K为6,返回False。 8 要求时间复杂度O(N+M),空间复杂度O(1)
思路:
1 思路: 从右上角开始对比 如果当前数比K大那么当前数往左走 如果当前数比K小那么当前数往下走 2 直到找到数K或者数走到边界不能再走为止 时间复杂度为O(N+M) 3 4 O(N+M)对应的最坏情况(找不到数或数就在左下角的位置): 5 1 3 5 6 6 2 5 7 9 7 4 6 8 10 8 k = 4
代码:
1 private static boolean find(int[][] arr, int num) { 2 int row = 0; 3 int col = arr[0].length - 1; 4 while (row != arr[0].length - 1 && col != 0) { 5 if (arr[row][col] == num) { 6 return true; 7 } else if (arr[row][col] > num) { 8 col--; 9 } else { 10 row++; 11 } 12 } 13 14 return false; 15 }