【剑指Offer】JZ19顺时针打印矩阵 Tag:[数组]

JZ19顺时针打印矩阵

    tag:数组

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字

例如,如果输入如下 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,2] , [3,4] ]

返回值

[1,2,4,3]

解题思路

我们可以把题目抽象化为 给一个二位矩阵,顺时针螺旋打印矩阵,再结合图示,就很好理解了。

为了方便讲解,我们把矩阵做如下定义:

图例
我们对矩阵做循环打印,关键在于找到其临界条件和对应关系,由于我们定义了up,down,left,right几个变量,所以每当up行打印完毕后:up可以向下移动一行
同理down可以向上移动一行、left可以向右移动一列、right可以向左移动一列
当我们的矩阵打印全部完毕之后,我们可以显而易见的发现,只要在我们每一次对四个变量移动时,判断它们是否符合边界条件,就可以判断出我们是否需要退出循环:

当up打印完当前行,向下移动一行时(up++)
判断 up > down 如果为true 则break跳出循环;
当right打印完当前列,向左移动一列时(right–)
判断 right < left 如果为true 则break跳出循环;
(同理,可以理解为 left > right 结果为false 则跳出循环)
当down打印完当前行,向上移动一行时(down–)
判断 down < up 如果为true 则break跳出循环;
当left打印完当前列,向右移动一列时(left++)
判断 left > right 如果为true 则break跳出循环;

同时,在对行列做循环时,要注意当前循环的边界条件,注意是行还是列,还有循环到什么位置,具体可见代码。

代码部分

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       ArrayList<Integer> result = new ArrayList<>();
       
       int up = 0;
       int down = matrix.length-1;
       int left = 0;
       int right = matrix[0].length-1;
       while(true){
           for(int col=left;col<=right;col++){
               result.add(matrix[up][col]);
           }
           up++;
           if(up > down){
               break;
           }
           
           for(int row=up;row<=down;row++){
               result.add(matrix[row][right]);
           }
           right--;
           if(left > right){
               break;
           }
           
           for(int col=right;col>=left;col--){
               result.add(matrix[down][col]);
           }
           down--;
           if(up > down){
               break;
           }
           
           for(int row=down;row>=up;row--){
               result.add(matrix[row][left]);
           }
           left++;
           if(left > right){
               break;
           }
       }
        return result;
    }
}

时间复杂度:O(mn), 矩阵中每个元素遍历一次

空间复杂度:O(mn), 每个元素需要存下来

电脑没电了,就到这啦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值