剑指offer——顺时针打印矩阵(基本属于纯粹的找规律)

面20

题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
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.

思路:
顺时针打印,读取的顺序是有规律的,即往右,往下,往左,往上。因此可以写一个循环。并且声明一个list变量,往list中按顺序存放数据,当list中变量数量等于数组大小时,跳出while循环。


一开始写的程序报错:

报错:
测试用例:
[[1]]

对应输出应该为:

[1]

你的输出为:

java.lang.ArrayIndexOutOfBoundsException: 1

public static ArrayList<Integer> printMatrix(int [][] matrix) {
        if(matrix==null)
            return null;
        int m = matrix.length;
        int n = matrix[0].length;
        if(m==0||n==0)
            return null;
        int[][] flag = new int[m][n];
        int num = m*n;
        ArrayList<Integer> list = new ArrayList();
        while(list.size()!=num){
            int i = 0;
            int j = 0; // 这个位置也有问题,每次while循环会重新置0
            for(;j<n;j++){
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            } // 这里一开始跳出循环是因为j越界

            for(;i<m;i++){
                if(flag[i][j]!=1){  // 不加处理,继续用越界的j,就出现指针越界错误
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }

            for(;j>=0;j--){
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }

            for(;i>=0;i--){
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }


        }

        return list;
    }

AC代码:

public static ArrayList<Integer> printMatrix(int [][] matrix) {
        if(matrix==null)
            return null;
        int m = matrix.length;
        int n = matrix[0].length;
        if(m==0||n==0)
            return null;
        int[][] flag = new int[m][n];
        int num = m*n;
        ArrayList<Integer> list = new ArrayList();
        int i = 0;
        int j = 0;
        list.add(matrix[0][0]);
        flag[0][0] = 1; //为了构成之后能够循环的逻辑,把第一个元素放在了循环体外
        while(list.size()!=num){

            for(++j;j<n;j++){ //直接++j
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }
            --j; // 因为跳出前面for循环有两种情况,一种是越界,一种是遇到了已经被访问过的元素,所以,都需要将j减1
            for(++i;i<m;i++){
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }
            --i;

            for(--j;j>=0;j--){
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }
            ++j;

            for(--i;i>=0;i--){
                if(flag[i][j]!=1){
                    list.add(matrix[i][j]);
                    flag[i][j] = 1;
                }
                else
                    break;
            }
            ++i;


        }

        return list;
    }

不需要boolean数组也可以,因为按照规律来就能正确遍历

public class Printer {
    public int[] clockwisePrint(int[][] mat, int n, int m) {
       
        // write code here
        int startX = 0;
        int endX = m - 1;
        int startY = 0;
        int endY = n - 1;
        int index = 0;
        int[] result = new int[n * m];
 
        while (startX <= endX && startY <= endY) {
 
            // 从左到右打印
            if(startX <= endX){
                for (int i = startX; i <= endX; i++) {
                    result[index++] = mat[startY][i];
                }
            }
             
 
            // 从上往下打印
 
            if (startY < endY) {
 
                for (int i = startY + 1; i <= endY; i++) {
                    result[index++] = mat[i][endX];
                }
            }
 
            // 从右往左打印
            if (startX < endX && endY > startY) {
                for (int i = endX - 1; i >= startX; i--) {
                    result[index++] = mat[endY][i];
                }
            }
             
            // 从下往上打印
            if (startY < endY && endX > startX) {
                for (int i = endY - 1; i >= startY + 1; i--) {
                    result[index++] = mat[i][startX];
                }
            }
 
            startX++;
            endX--;
            startY++;
            endY--;
        }
        return result;
     
     
    }
}

or

public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       int n = matrix.length;
        int m = matrix[0].length;
        int flag = Integer.MAX_VALUE;
        ArrayList<Integer> list = new ArrayList<>();
        int startLine = 0;
        int startRow = -1;
        while(list.size()!=n*m){
            for(int j = startRow+1; j<m; j++){
                if(matrix[startLine][j]!=flag){
                    list.add(matrix[startLine][j]);
                    matrix[startLine][j] = flag;
                    if(j==m-1) startRow = j;
                }
                else{
                    startRow = j-1;
                    break;
                }
            }
            for(int i = startLine+1; i<n; i++){
                if(matrix[i][startRow]!=flag){
                    list.add(matrix[i][startRow]);
                    matrix[i][startRow] = flag;
                    if(i==n-1) startLine = i;
                }
                else{
                    startLine = i-1;
                    break;
                }
            }
            for(int j = startRow-1; j>=0 ; j--){
                if(matrix[startLine][j]!=flag){
                    list.add(matrix[startLine][j]);
                    matrix[startLine][j] = flag;
                    if(j==0) startRow = j;
                }
                else{
                    startRow = j+1;
                    break;
                }
            }
            for(int i = startLine-1; i>=0; i--){
                if(matrix[i][startRow]!=flag){
                    list.add(matrix[i][startRow]);
                    matrix[i][startRow] = flag;
                    if(i==0) startLine = i;
                }
                else{
                    startLine = i+1;
                    break;
                }
            }
        }
        return list;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值