LeetCode第54题:螺旋矩阵

LeetCode第54题:螺旋矩阵

问题描述

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

方法一(有点麻烦了)

思路分析

  • 按圈进行遍历,对每一圈进行遍历时,保持左闭右开的步骤进行处理
  • 最后要考虑是否会剩下中间的一行或一列需要单独进行处理
    详见代码。

代码

class Solution
{
    public List<Integer> spiralOrder(int[][] matrix)
    {
        List<Integer> retList = new ArrayList<>();
        int m = matrix.length;
        int n = matrix[0].length;
        int loop = Integer.min(m, n) / 2;
        int startx = 0;// 每一圈的遍历初始位置的行号
        int starty = 0;// 每一圈的遍历初始位置的列号
        int i = startx;
        int j = starty;
        int offset = 1;
        while (loop-- > 0)
        {
            // 从左向右遍历,不包括最右端的值
            for (j = starty; j < starty + n - offset; j++)
            {
                retList.add(matrix[startx][j]);
            }
            // 从上向下遍历,不包括最下端的值
            for (i = startx; i < startx + m - offset; i++)
            {
                retList.add(matrix[i][j]);
            }
            // 从右向左遍历,不包括最左端的值
            for (; j > starty; j--)
            {
                retList.add(matrix[i][j]);
            }
            // 从下向上遍历,不包括最上端的值
            for (; i > startx; i--)
            {
                retList.add(matrix[i][j]);
            }
            startx++;
            starty++;
            offset += 2;
        }
        // 是否会剩余未遍历到的行或列,取决于行、列数的最小值,是否为奇数
        if (Integer.min(m, n) % 2 == 1)
        {
            if (m < n)// 剩余某一行未进行遍历
            {
                for (int k = m / 2; k < m / 2 + n - m / 2 * 2; k++)
                {
                    retList.add(matrix[m / 2][k]);
                }
            }
            else// 剩余某一列未进行遍历
            {
                for (int k = n / 2; k < n / 2 + m - n / 2 * 2; k++)
                {
                    retList.add(matrix[k][n / 2]);
                }
            }
        }
        return retList;
    }
}

方法二

思路分析

  • 上面方法的循环条件写得不好,因为在行数或列数为奇数时需要单独处理中间的那一行或一列。
  • 下面的方法在对每行进行遍历前,判断是否越界,遍历完每行或每列后,立即对这一行(列)的边界进行处理,思路上更加清晰,代码也更简洁。
    详见代码。

代码

class Solution
{
    public List<Integer> spiralOrder(int[][] matrix)
    {
        List<Integer> retList = new ArrayList<>();
        int rowBegin = 0;
        int rowEnd = matrix.length - 1;
        int colBegin = 0;
        int colEnd = matrix[0].length - 1;
        while (rowBegin <= rowEnd && colBegin <= colEnd)
        {
            // 从左向右遍历
            for (int j = colBegin; j <= colEnd; j++)
            {
                retList.add(matrix[rowBegin][j]);
            }
            // 该行遍历完成,使这一圈的最开始一行 rowBegin+1
            rowBegin++;
            // 从上向下遍历
            for (int i = rowBegin; i <= rowEnd; i++)
            {
                retList.add(matrix[i][colEnd]);
            }
            // 该列遍历完成,使这一圈的最后一列 colEnd-1
            colEnd--;
            // 从右向左遍历。需要判断是否重复遍历
            if (rowBegin <= rowEnd)
            {
                for (int j = colEnd; j >= colBegin; j--)
                {
                    retList.add(matrix[rowEnd][j]);
                }
            }
            // 该行遍历完成,使这一圈的最后一行 rowEnd-1
            rowEnd--;
            // 从下向上遍历。需要判断是否重复遍历
            if (colBegin <= colEnd)
            {
                for (int i = rowEnd; i >= rowBegin; i--)
                {
                    retList.add(matrix[i][colBegin]);
                }
            }
            // 该列遍历完成,使这一圈的最开始一列 colBegin+1
            colBegin++;
        }
        return retList;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值