• 跟左神学算法4 基础数据结构(矩阵相关)


    内容:

    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 }
  • 相关阅读:
    上传图片2(接上一篇)
    上传图片2
    上传图片
    SQL Server基础之存储过程
    C#导入Excel、Excel导入、导入.xls 、导入.xlsx、Excel2003版本、Excel2007版本
    C#使用 System.Net.Mail发送邮件功能
    C#发送邮件三种方法,Localhost,SMTP,SSL-SMTP
    angular模板
    从“繁”到“简”进行数组去重
    CSS强制英文、中文换行与不换行
  • 原文地址:https://www.cnblogs.com/wyb666/p/10159403.html
Copyright © 2020-2023  润新知