【数组】【打卡63天】《剑指Offer》2刷:JZ29 顺时针打印矩阵

代码注释详细!

1.题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵,以及输出的顺序:

[[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]

2.算法分析

①一层一层的从外向里打印,每一层都有相同的步骤,唯一不同的是上下左右的边界不同。 

因此使用四个变量top,right,down,left作为边界值。从而定义当前最外层。打印当前最外层的顺序:从左到右打印最上一行->从上到下打印最右一行->从右到左打印最下一行->从下到上打印最左一行。

注意:应当注意只有在 top != down 时才打印最下一行,也就是在当前最外层的行数大于 1 时才打印最下一行,这是因为当前最外层只有一行时,继续打印最下一行,会导致重复打印。打印最左一行也要做同样处理。

知识补充:

二维数组的长度问题:

<1> arr.length:表示二维数组的行数;

<2> arr[0].length:表示二维数组的列数;

<3>行数列数的范围:

a[3][4]:表示的是一个3行4列的二维数组:

行数范围:0---2    0---arr.length-1;

列数范围:0---3    0---arr[0].length-1

 3.代码实现

import java.util.*;
/*
    一层一层的从外向里遍历,每一层都是相同的处理步骤
    只有上、下、左、右的边界值会改变。
    注意:打印的时候,上一行和最下一行是不能重叠的,防止重复打印。
    left   right也是一样,是不能重叠的。
    
    知识补充:
    1.二维数组的行数:arr.length;
    2.二维数组的列数:arr[0].length - 1
    
*/
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        // 定义结果集
        ArrayList<Integer> result = new ArrayList<Integer>();
        // 定义上边界值
        int top = 0;
        // 定义下边界值
        int down = matrix.length - 1;
        // 定义左边界值
        int left = 0;
        //定义右边界值
        int right = matrix[0].length - 1;
        // 条件判断,
        while(top <= down && left <= right){
            // 上:第top行的第i个元素,i的范围是二维数组最左边的元素到最右边的元素所在列
            for(int i = left;i <= right;i++){
                result.add(matrix[top][i]);
            }
            // 右:第二行的最后一个元素开始,j的范围是是小于元素所在列的值
            for(int j = top + 1;j <= down;j++){
                result.add(matrix[j][right]);
            }
            // 判断上边界值不等于下边界值
            if(top != down){
                // 下:x从最下面一行开始
                for(int x = right-1;x >= left;x--){
                    result.add(matrix[down][x]);
                }
            }
            // 判断左边界值不等于右边界值
            if(left != right){
                // 左:这边y的值是大于top的,因为top那一个元素已经遍历过了。
                for(int y = down-1;y > top;y--){
                    result.add(matrix[y][left]);
                }
            }
            top++;
            down--;
            left++;
            right--;
        }
        return result;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值