天天看点

剑指Offer-顺时针打印矩阵48.顺时针打印矩阵

48.顺时针打印矩阵

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

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]


           

思路

这道题思路不难,就是处理边界的时候巨恶心。先来看思路。

就是找到矩阵中左上角的点和右下角的点,两个点的横纵坐标控制着打印的边界。

注意要考虑矩阵不是方阵的情况以及矩阵只有一行或者一列的情况。对于这些情况,需要动态地判断边界是否重合。具体判断方法请看注释。这是我看到的比较容易理解的代码写法。

class Solution {
    public int[] spiralOrder(int[][] matrix) {

        if(matrix==null || matrix.length==0 || matrix[0].length==0)
        {
            return new int[0];
        }
        int m=matrix.length;
        int n=matrix[0].length;
        int[] res=new int[m*n];
        int index=0;
		//定义出边界
        int lx=0;
        int ly=0;
        int rx=m-1;
        int ry=n-1;
		//循环推出条件,注意包含等于,对于方阵来说,等于的时候就是中心的点
        while(lx<=rx && ly<=ry)
        {
            //从左到右正常全部打印此行
            for(int i=ly;i<=ry;i++)
            {
                res[index++]=matrix[lx][i];
            }
            lx++;//打印完之后,这一行就"没用了",所以++为下次循环做准备

            //从上到下打印
            for(int i=lx;i<=rx;i++)
            {
                res[index++]=matrix[i][ry];
            }
            ry--;//同理,打印完这一列,它就"没用了",为下次循环做准备
			
            //打印到这里,我们需要判断,因为从左到右打印时,lx++了,如果lx++之后大于了rx,那么说明lx之前和
            //rx是相等的,那就意味着,这是个"长方形"矩阵而非正方形.且行数比列数少.
            //也就意味着,从左到右打印和从右到左打印的结果是一样的,无需重复打印.
            if(lx<=rx)
            {
                for(int i=ry;i>=ly;i--)
                {
                    res[index++]=matrix[rx][i];
                }
            }
            rx--;
			
            //与上个if分析同理.
            if(ly<=ry)
            {
                for(int i=rx;i>=lx;i--)
                {
                    res[index++]=matrix[i][ly];
                }
            }
            ly++;
        }
        return res;
    }
}