矩阵简单问题(Java)

问题: 顺时针打印二维方阵:

1 2 3 4 15

5 6 7 8 14

9 10 11 12 13

13 14 15 16

java 复制代码
public class Test1 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{
                {1, 2, 3, 4,100},
                {5, 6, 7, 8,101},
                {9, 10, 11, 12,102},
                {13, 14, 15, 16,103}
        };
        f1(arr);
    }
    static void f1(int[][] arr) {
        int leftRow = 0, leftCol = 0; //左上
        int rightRow = arr.length - 1, rightCol = arr[0].length - 1; //右下
        while (leftRow <= rightRow && leftCol <= rightCol) {
            for (int i = leftCol; i <= rightCol; i++) {
                System.out.print(arr[leftRow][i] + " ");
            }
            for (int i = leftRow + 1; i <= rightRow; i++) {
                System.out.print(arr[i][rightCol] + " ");
            }
            for (int i = rightCol - 1; i >= leftCol; i--) {
                System.out.print(arr[rightRow][i] + " ");
            }
            for (int i = rightRow - 1; i > leftRow; i--) {
                System.out.print(arr[i][leftCol] + " ");
            }
            leftRow++;
            leftCol++;
            rightRow--;
            rightCol--;
        }
    }
}

问题:0所在的行和列清零

1 2 3 4

6 0 7 8

9 10 0 11

只能先遍历一遍记录下0的位置,然后在改0

java 复制代码
public class Test1 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{
                {1, 2, 3, 4,100},
                {5, 6, 0, 8,101},
                {9, 10, 11, 0,102},
                {13, 14, 15, 16,103}
        };
        f2(arr);
        for (int[] ints : arr) {
            for (int i : ints) {
                System.out.print(i+" ");
            }
            System.out.println("");
        }
    }
    static void f2(int[][] arr){
        int m = arr.length,n = arr[0].length;
        int[] row = new int[m];
        int[] col = new int[n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(arr[i][j] == 0){
                    row[i]=1;
                    col[j]=1;
                }
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(row[i]==1 || col[j]==1){
                    arr[i][j]=0;
                }
            }
        }
    }
}

问题:"Z"型打印

1,2, 3, 4

5,6, 7, 8

9,10,11,12 结果为1 2 5 9 6 3 4 7 10 11 8 12

java 复制代码
public class Test1 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{
                {1,2, 3, 4},
                {5,6, 7, 8},
                {9,10,11,12}
        };
        f3(arr);
    }
    static void f3(int[][] arr){
        int row = 0,m = arr.length;
        int col = 0,n = arr[0].length;
        boolean flag = true;  //控制是斜向上打印还是斜向下打印
        while(row<m && col<n){
            if(flag){
                System.out.print(arr[row][col]+" ");
                if(row==0 && col <n-1){ //斜上打印,碰到上端,就打印右边的,然后在斜向下
                    col++;
                    flag=false;
                } else if (row>0 && col== n-1) {//斜上打印,碰到右端,就打印下边的,然后在斜向下
                    row++;
                    flag=false;
                }else {
                    row--;
                    col++;
                }
            }else {
                System.out.print(arr[row][col]+" ");
                if(col==0 && row < m-1){ //斜下打印,碰到左端,就打印下边的,然后在斜向上
                    row++;
                    flag=true;
                } else if (col > 0 && row == m - 1) {//斜下打印,碰到下端,就打印右边的,然后在斜向上
                    col++;
                    flag=true;
                }else {
                    row++;
                    col--;
                }
            }
        }
    }
}

给定一个n*n矩阵,值只有0和1 返回边框为1的最大正方形的边长长度

0,1,1,1,1

0,1,0,0,1

0,1,0,0,1

0,1,1,1,1

0,1,0,1,1 返回4

java 复制代码
public class Test1 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{
                {0,1,1,1,1},
                {0,1,0,0,1},
                {0,1,0,0,1},
                {0,1,1,1,1},
                {0,1,0,1,1}
        };
        System.out.println(f4(arr));
    }
    static int f4(int[][] arr){
        int n = arr.length;
        helper(arr);
        while(n>=1){
            for(int i=0;i<arr.length;i++){
                for(int j=0;j<arr.length;j++){
                    if(i+n>arr.length || j+n>arr.length){
                        continue;
                    }
                    /*if(test(arr,i,j,n)){
                        return n;
                    }*/

                    if(help[i][j][0]>=n && help[i][j][1]>=n && help[i][j+n-1][1]>=n && help[i+n-1][j][0]>=n)
                        return n;
                }
            }
            n--;
        }
        return 0;
    }
    static int[][][] help;  // 0为右边1的个数,1为下面1的个数
    //构建三维数组,维护每一元素1的个数
    static void helper(int[][] arr){
        int n=arr.length;
        help=new int[n][n][2];
        int row= n-1;
        //先填充好最下面的一行
        for(int j=n-1;j>=0;j--){
            int value = arr[row][j];
            if(value==1){
                if(j==n-1)help[row][j][0]=1;
                else help[row][j][0]=help[row][j+1][0]+1;

                help[row][j][1]=1;
            }
        }
        row--;
        //在逐渐向上遍历
        for (int i=row;i>=0;i--){
            for(int j=n-1;j>=0;j--){
                int value = arr[i][j];
                if(value==1){
                    if(j==n-1)help[i][j][0]=1;
                    else help[i][j][0]=help[i][j+1][0]+1;

                    help[i][j][1]=help[i+1][j][1]+1;
                }
            }
        }
    }
}

问题:求最大子矩阵累加和,其值有正、有负、有0,返回子矩阵的最大累加和

解法:将矩阵中每行的相同列的元素逐渐相加,转化为 无序的一维数组求最大连续累加和。

那么我们先求一个一维无序数组arr,返回arr中子数组(连续)的最大累加和。

java 复制代码
public class Test2 {
    public static void main(String[] args) {
        
    }
    static int f1(int[] arr){
        if(arr.length==0) return 0;
        int sum=arr[0],max=arr[0];
        int left = 0, right = 0;
        for(int i=1;i<arr.length;i++){
            if(sum<=0){
                sum=arr[i];
                left=i;
                //这里不能用continue,因为不能保证最大累加和大于0,可能每个元素都小于0.
            }else sum+=arr[i];

            if(sum>max){
                max=sum;
                right=i;
            }
        }
        System.out.println("left="+left+" ,right="+right);
        return max;
    }
}

然后按列求和,维护一个sum数组,sum[i]为第i列的元素求和,先是从第0行到最后一行的所有列求和,每加一次,求一次sum数组的最大子序列。然后在清空sum,然后在是第1行到最后一行的所有列求和,每次求和,求一次sum数组的最大子序列,然后在从第2行开启,直到遍历完所有行。

java 复制代码
public class Test2 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{
                {-90,48,78},
                {64,-40, 64},
                {-81,-7,66}
        };
        System.out.println(f2(arr));
    }
    static int f1(int[] arr){
        if(arr.length==0) return 0;
        int sum=arr[0],max=arr[0];
        int left = 0, right = 0;
        for(int i=1;i<arr.length;i++){
            if(sum<=0){
                sum=arr[i];
                left=i;
                //这里不能用continue,因为不能保证最大累加和大于0,可能每个元素都小于0.
            }else sum+=arr[i];

            if(sum>max){
                max=sum;
                right=i;
            }
        }
        System.out.println("left="+left+" ,right="+right);
        return max;
    }
     
    static int f2(int[][] arr){
        int row = 0; //从第一行作为起始行
        int m = arr.length;
        int n = arr[0].length;
        //按列求和
        int[] sums = new int[m];
        int max=0; //历史子矩阵累加和
        while(row<m){
            for(int i=row;i<m;i++){
                for(int j=0;j<n;j++){
                    sums[j]+=arr[j][i];
                }
                //累加完成
                //求无序一维数组的最大连续累加和
                int t = f1(sums);
                max=Math.max(max,t);
            }
            //以下一行作为起始行,
            Arrays.fill(sums,0);
            row++;
        }
        return max;
    }
}
相关推荐
源码~185381628006 小时前
短视频矩阵系统前端搭建技术解析,支持OEM
前端·矩阵·音视频
最好Tony8 小时前
深度学习blog-深刻理解线性变换和矩阵
人工智能·深度学习·矩阵·线性变换
graceyun10 小时前
牛客网刷题 ——C语言初阶(5操作符)——BC90 矩阵计算
c语言·算法·矩阵
7yewh16 小时前
LeetCode 力扣 热题 100道(二十八)矩阵置零(C++)
c语言·数据结构·c++·算法·leetcode·矩阵
阑梦清川1 天前
线性代数自学资源推荐&&我的个人学习心得
线性代数·数学建模
你好,赵志伟2 天前
线性代数考研笔记
笔记·线性代数·考研
M姐实验室2 天前
分类模型评估利器-混淆矩阵
人工智能·python·矩阵·分类
程序员shen1616112 天前
短视频矩阵源码开发/saas矩阵部署/api矩阵源码接口搭建
数据结构·数据库·python·线性代数·算法·矩阵
15年网络推广青哥3 天前
TikTok矩阵运营:如何提高账号粉丝量?
大数据·人工智能·矩阵