例题集 矩阵

  1. 转圈打印矩阵
  2. 旋转正方形矩阵
  3. 之字形打印矩阵
  4. 在行跟列都排好序的矩阵中找数

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)

思路:

  1. 找到矩阵左上角的位置和右下角的位置
  2. 按转圈的方向先打印最外层
  3. 对于最外层,要判断是否只有一行或者一列
  4. 打印完最外层,在打印里面的一层…重复步骤4
  5. 对于打印里面一层,要判断是否越界
    在这里插入图片描述
public class sprialOrderPrint14 {

    public static void main(String[] args) {
        int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
        sprialOrderPrint(arr);
    }

    public static void sprialOrderPrint(int[][] arr){
        //左上行
        int LeftTopRow = 0;
        //左上列
        int LeftTopColumn = 0;
        //右下行    ->    二维矩阵的行数
        int RightDownRow = arr.length - 1;
        //右下列    ->    二维矩阵的列数
        int RightDownColumn = arr[0].length - 1;

        while (LeftTopRow <= RightDownRow && LeftTopColumn <= RightDownColumn){
            printEdge(arr,LeftTopRow++,LeftTopColumn++,RightDownRow--,RightDownColumn--);
        }
    }

    private static void printEdge(int[][] arr, int leftTopRow, int leftTopColumn, int rightDownRow, int rightDownColumn) {
        //只有一行时
        if (leftTopRow == rightDownRow){
            for (int i = leftTopColumn;i <= rightDownColumn;i++){
                System.out.println(arr[leftTopRow][i]);
            }
        }else if (leftTopColumn == rightDownColumn){
            //还有一列时
            for (int i = leftTopRow; i <= rightDownRow;i++){
                System.out.println(arr[i][leftTopColumn]);
            }
        }else {
            //还有多行多列时

            //当前列
            int curColumn = leftTopColumn;
            //当前行
            int curRow = leftTopRow;

            while (curColumn != rightDownColumn){
                System.out.println(arr[leftTopRow][curColumn++]);
            }
            while (curRow != rightDownRow){
                System.out.println(arr[curRow++][curColumn]);
            }
            while (curColumn != leftTopColumn){
                System.out.println(arr[curRow][curColumn--]);
            }
            while (curRow != leftTopRow){
                System.out.println(arr[curRow--][curColumn]);
            }
        }
    }
}

2.旋转正方形矩阵
要求
(1)给定一个整型正方形矩阵matrix,请把该矩阵调整成顺时针旋转90度的样子
(2)时间复杂度O(1)

思路:
(1)先旋转最外层矩阵,依次调换位置
(2)在旋转里层矩阵
在这里插入图片描述

public class Rorate15 {

    public static void main(String[] args) {
        int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
        rorate(arr);
        for (int i = 0;i <= arr.length - 1;i++){
            for (int y = 0; y <= arr[0].length - 1;y++){
                System.out.println(arr[i][y]);
            }
        }
    }

    public static void rorate(int [][] arr){
        //左上行
        int LeftTopRow = 0;
        //左上列
        int LeftTopColumn = 0;
        //右下行    ->    二维矩阵的行数
        int RightDownRow = arr.length - 1;
        //右下列    ->    二维矩阵的列数
        int RightDownColumn = arr[0].length - 1;

        while (LeftTopRow <= RightDownRow){
            rorateEdge(arr,LeftTopRow++,LeftTopColumn++,RightDownRow--,RightDownColumn--);
        }
    }

    private static void rorateEdge(int[][] arr, int leftTopRow, int leftTopColumn, int rightDownRow, int rightDownColumn) {
        //记录正方形一行/一列有几个元素
        int times = rightDownColumn - leftTopColumn;

        for (int i = 0; i < times; i++){
            System.out.println("i" + i);
            //左上 右上 交换
            swap(arr,leftTopRow,leftTopColumn + i,leftTopRow + i,rightDownColumn);
            //左上 右下 交换
            swap(arr,leftTopRow,leftTopColumn + i,rightDownRow,rightDownColumn - i);
            //左上 左下 交换
            swap(arr,leftTopRow,leftTopColumn + i,rightDownRow - i,leftTopColumn);
        }
    }

    private static void swap(int[][] arr, int leftTopRow, int leftTopColumn, int i, int leftTopColumn1) {
        int tmp =arr[leftTopRow][leftTopColumn];
        arr[leftTopRow][leftTopColumn] = arr[i][leftTopColumn1];
        arr[i][leftTopColumn1] = tmp;
    }
}

3.之字形打印矩阵
要求:额外空间复杂度为O(1)
在这里插入图片描述
思路:
用两个点作为标记点
对于A点,aC一直++,当aC = arr.length - 1时,aR开始++
对于B点,bR一直++。当bC = arr[0].length - 1时,bC开始++
在这里插入图片描述

//16.之字形打印矩阵
//要求:额外空间复杂度为O(1)
public class ZhiZagPrintMatrix17 {

    public static void main(String[] args) {
        int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};
        zhiZagPrint(arr);
    }


    private static void zhiZagPrint(int [][] arr){
        //A行
        int aR = 0;
        //A列
        int aC = 0;
        //B行
        int bR = 0;
        //B列
        int bC = 0;
        //标记最后一行下标
        int endR = arr.length - 1;
        //标记最后一列下标
        int endC = arr[0].length - 1;
        //判断从下往下打印还是从下往上打印
        boolean fromUp = true;

        //A行 != 最后一行  或者 B列 != 最后一列 打印结束
        while (aR != arr.length){
            print(arr,fromUp,aR,aC,bR,bC);
            aR = aC == endC ? aR + 1: aR;
            aC = aC == endC ? aC : aC + 1;
            bC = bR == endR ? bC + 1: bC;
            bR = bR == endR ? bR : bR + 1;
            fromUp = !fromUp;
        }
    }

    private static void print(int[][] arr, boolean fromUp, int aR, int aC, int bR, int bC) {
        if (fromUp){
            //从上往下打印
            while (aR <= bR){
                System.out.println(arr[aR++][aC--]);
            }

        }else {
            //从下往上打印
            while (bC <= aC){
                System.out.println(arr[bR--][bC++]);
            }
        }
    }
}

4.在行跟列都排好序的数组中找数
从最右上角的数开始找起
如果当前数cur > num,说明cur下边一列的数都>num,curC–;
如果当前数cur < num,说明cur左边一行的数都<num,curR++;
在这里插入图片描述
17.在行跟列都排好序的矩阵中找数

public class MatrixInContains17 {
    public static void main(String[] args) {

        int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};
        Boolean contains = matrixInContains17(arr, 9);
        if (contains){
            System.out.println("true");
        }else {
            System.out.println("false");
        }
    }

    private static Boolean matrixInContains17(int[][] arr,int num){
        int curR = 0;
        int curC = arr[0].length - 1;
        Boolean contains = false;

        int i = 0;
        while (curC > -1 && curR < arr.length){
            if (arr[curR][curC] < num){
                //则这一列往下都不可能
                curR++;
            }else if (arr[curR][curC] > num){
                //则左边一行都不可能
                curC--;
            }else if (arr[curR][curC] == num){
                return true;
            }
        }
        return contains;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值