几道与矩阵有关的练习题

1、转圈打印矩阵

【题目】 给定一个整型矩阵matrix, 请按照转圈的方式打印它。
例如: 1 2 3 4
    5 6 7 8
    9 10 11 12
   13 14 15 16
打印结果为: 1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9,5, 6, 7, 11, 10
【要求】 额外空间复杂度为O(1)。
思路:如果给出左上方的顶点的坐标A(tr,tl),和右下角的点B(dr,dl)
(top row,top line),(down row,down line),这样可以轻松实现打印最外面的所有数字,把这个过程封装成个函数,然后循环调用。

code

package exercise;
/*
转圈打印矩阵
 */
class MatCirclePrint {
    private Integer[][]  mat;
    public MatCirclePrint(Integer[][] mat){

        this.mat=mat;
    }
    public void CirclePrintmat(){
        int tr=0,tl=0,dr=mat.length-1,dl=mat[0].length-1;
        while (tr<=dr && tl<=dl){
            printEdge( tr++, tl++, dr--, dl--);
        }

    }

    public void printEdge(Integer tr,Integer tl,Integer dr,Integer dl){
        //tr toprow,dr downrow;[tr,tl]最左上角1的坐标,[dr,dl]最右下角
        if (tr==dr){//数据就一行
            while (tl<=dl){
                System.out.print(mat[0][tl]);
                System.out.print(" ");
                tl++;
            }
        }else if (tl==dl){//数据就一列
            while (tr<=dr){
                System.out.println(mat[tr][0]);
                tr++;
            }
        }
        else {
            int curL=tl;//当前走到哪一列了
            int curR=tr;//当前走到哪一行了
            while(curL<dl){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curL++;
            }
            while (curR<dr){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curR++;
            }
            while (curL>tl){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curL--;
            }
            while (curR>tr){
                System.out.print(mat[curR][curL]);
                System.out.print(" ");
                curR--;
            }

        }
    }

    public static void main(String[] args) {
        MatCirclePrint mcp1=new MatCirclePrint(new Integer[][]{{1,2,3,4}});
        mcp1.printEdge(0,0,0,3);
        System.out.println();
        System.out.println("-------------分割线--------------------");
        MatCirclePrint mcp2=new MatCirclePrint(new Integer[][]{{5},{6},{7},{8}});
        mcp2.printEdge(0,0,3,0);
        System.out.println("-------------分割线--------------------");
        MatCirclePrint mcp3=new MatCirclePrint(new Integer[][]{{1, 2, 3, 4},
                                                                {5, 6, 7, 8},
                                                                {9,10,11,12},
                                                                {13,14,15,16}
                                                                });
        System.out.println("printEdge函数测试!");
        mcp3.printEdge(0,0,3,3);
        System.out.println("");
        System.out.println("-------------分割线--------------------");
        System.out.println("测试CirclePrintmat()");
        mcp3.CirclePrintmat();

    }

}

2、旋转正方形矩阵

旋转正方形矩阵
【题目】 给定一个整型正方形矩阵matrix, 请把该矩阵调整成
顺时针旋转90度的样子。
【要求】 额外空间复杂度为O(1)

package exercise;
/*
转圈打印矩阵
 */
class Rotate {


    public void rotate(int[][] matrix) {
        int startR=0;
        int startL=0;
        int endR  =matrix.length-1;
        int endL  =matrix[0].length-1;
        while(startR<=endR){
            rotedge(matrix,startR++,startL++,endR--,endL--);
        }
    }
    public void rotedge(int[][]matrix,int topRow,int topLine,int downRow,int downLine ){
        int tem=0;
        int times=downLine-topLine;
        for(int i=1;i<=times;i++){
            tem=matrix[topRow][topLine+i];
            matrix[topRow][topLine+i]=matrix[downRow-i][topLine];
            matrix[downRow-i][topLine]=matrix[downRow][downLine-i];
            matrix[downRow][downLine-i]=matrix[topLine+i][downLine];
            matrix[topLine+i][downLine]=tem;

        }
    }

}

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)
思路:构建A,B两个点,A点一直右移,走到最右端下移;
   B点一直下移,走到最下端右移;
   一直打印A,B两点连线上的数据

   

代码如下:

package exercise;
 class PrintZhiMat{
    public void printZhimat(int[][]arr){
        int tem_ar=0;
        int tem_al=0;
        int tem_br=0;
        int tem_bl=0;
        int count=0;
        while (tem_ar!=arr.length ){
            //循环终止条件,A来到最后一行
            printdiagonal(arr,tem_ar,tem_al,tem_br,tem_bl,count%2);
            //下面的判断写成三目运算符更好
            if (tem_al<arr[0].length-1){
                tem_al++;
            }else {
                tem_ar++;
            }
            if (tem_br<arr.length-1){
                tem_br++;
            }
            else {
                tem_bl++;
            }
            count++;
            //System.out.printf("这是第%d次循环",count++);

        }


    }
public void  printdiagonal(int[][] arr,int ar,int al,int br,int bl,int flag){
        //A(ar,al),B(br,bl)
        int tem_ar=ar;
        int tem_al=al;
        int tem_br=br;
        int tem_bl=bl;
        if (flag==0){
            while (tem_ar<=tem_br){
                System.out.print(arr[tem_br--][tem_bl++]);
                System.out.print(" ");
            }
        }
        if (flag==1){
            while (tem_ar<=tem_br){
                System.out.print(arr[tem_ar++][tem_al--]);
                System.out.print(" ");
            }
        }

    }


    public static void main(String[] args) {
        int[][] mat=new int[][]{{1,2,3,4},
                                {5,6,7,8},
                                {9,10,11,12},
                                {13,14,15,16} };
        PrintZhiMat pzt =new PrintZhiMat();
        pzt.printdiagonal(mat,0,3,3,0,0);
        System.out.println("\n----------------分割线-----------------");
        pzt.printdiagonal(mat,0,3,3,0,1);
        System.out.println("\n----------------分割线-----------------");
        pzt.printZhimat(mat);
    }

}

执行结果

13 10 7 4 
----------------分割线------------------------
4 7 10 13 
----------------分割线------------------------
1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16 

4 在已排好序的矩阵中查找数字

【题目】 给定一个有N*M的整型矩阵matrix和一个整数K,matrix的每一行和每一 列都是排好序的。 实现一个函数, 判断K是否在matrix中。 例如:
            0 1 2 5
            2 3 4 7
            4 4 4 8
            5 7 7 9
 如果K为7, 返回true; 如果K为6, 返回false。
【要求】 时间复杂度为O(N+M), 额外空间复杂度为O(1)
思路:
 选取左下角(或右上角)的点mat[mat.length-1][0]作为起点;
 当前的数比K小则向右走;
 当前的数比K大则向上走;
 临界条件,遍历的数走出mat

public class e8_findNumOrdered {


    public boolean findNumOrdered(int[][] mat, int K){
        int i=mat.length-1,j=0;
        while (i<mat.length  &&  j<mat[0].length){

            if (mat[i][j]==K){
                return true;
            }
            else if (mat[i][j]>K){
                i--;
            }else {
                j++;
            }

        }

        return false;
    }

    public static void main(String[] args) {
        int [][]arr={
                {1,3,5,7,9},
                {3,4,6,17,10},
                {9,11,12,20,35},
                {40,41,56,70,100}
        };
        e8_findNumOrdered  fno=new e8_findNumOrdered ();
        System.out.println(fno.findNumOrdered(arr,9));

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值