【剑指offer】顺时针打印矩阵

题目描述

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

解题思路

  • 判空:
    1. 二维数组的判空只有以下几种情况:null,[],[[]];
  • 逻辑:
    1. 获取二维数组的列数和行数;
    2. 声明2个标识,表明当前读数的方向(上、下、左、右);
    3. 声明4个变量并初始化,表明本次读数的最大、最小值,即循环结束条件;
    4. 如果当前正在从左往右读数,则,下次读数的起始位置的纵坐标就要加一,以第一次读第一行为例,因为本次读数已经把第一行最右边的数读了,所以下一次读数要从第二行开始,即min-height++;
    5. 如果当前正在从上往下读,则,下次读数的起始位置的横坐标要减一,以第一次读最右边的列为例,因为本次读数已经把最后一列最后一行的数读完了,所以下一次读数要从倒数第二行开始,即max-width–;
    6. 如果当前正在从右往左读,则,下次读数的起始位置的纵坐标要减一,道理同上,即max-height–;
    7. 如果当前正在从下往上读,则,下次读数的起始位置的横坐标要加一,道理同上,即min-width++;
    8. 结束当前列(或行)的循环之后,需要改变标识方向的变量,down(right);
    9. 读取行的循环结束条件为(j < maxWidth && right) || (j >= minWidth && !right);
    10. 读取列的循环结束条件为(i >= minHeight && !down) || (i < maxHeight && down);
    11. 最外层循环结束条件是所有的值都已经读完了,返回需要的结果。

代码

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return res;
        int width = matrix[0].length;
        int height = matrix.length;
        int minWidth = 0;
        int maxWidth = matrix[0].length;
        int minHeight = 0;
        int maxHeight = matrix.length;
        boolean right = true;
        boolean down = true;
        int count = 0;
        int i = 0;
        int j = 0;
        while(count < (width * height)){
            while((j < maxWidth && right) || (j >= minWidth && !right)){
                res.add(matrix[i][j]);
                count++;
                if(right){
                    j++;
                } else {
                    j--;
                }
            }
            if(right){
                ++minHeight;
                i = minHeight;
                // 因为在上面的循环中多加了一次j,所以需要减一
                j--;
            } else {
                --maxHeight;
                // maxHeight表示的是数组行数,因此在数组中读数的时候需要减一,获取当前的索引
                i = maxHeight-1;
                // 因为在上面的循环中多减了一次j,所以需要加一
                j++;
            }
            right = !right;
            while((i >= minHeight && !down) || (i < maxHeight && down)){
                res.add(matrix[i][j]);
                count++;
                if(down){
                    i++;
                } else {
                    i--;
                }
            }
            if(down){
                --maxWidth;
                // maxWidth表示的是数组列数,因此在数组中读数的时候需要减一,获取当前的索引
                j = maxWidth-1;
                // 因为在上面的循环中多加了一次j,所以需要减一
                i--;
            } else {
                ++minWidth;
                j = minWidth;
                // 因为在上面的循环中多减了一次j,所以需要加一
                i++;
            }
            down = !down;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值