leetcode 54. 螺旋矩阵

模拟法

  • 参考代码随想录:代码随想录-螺旋矩阵
  • 首先,需要确定定义边界的规则,从而确定模拟的区间,比如采用左闭右开,左闭右闭等。本题建议采用左闭右开,也就是起点闭合,终点打开。
  • 其次,循环次数也很重要,用来确定模拟什么时候结束。本题每转一圈是走2行和2列,因此模拟次数为行数和列数中最小值的一半。
  • 如果为奇数行或奇数列,每次走2行2列,最后会剩下1行或1列,因此最后需要模拟打印剩下的1行或一列。
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        if(matrix == null || matrix.length == 0)
            return res;
        int m = matrix.length, n = matrix[0].length;
        int minIdx = Math.min(m, n);
        int loop = minIdx / 2; // 模拟次数
        int startx = 0, starty = 0;
        int offset = 1; // 控制边界的偏移量
        int i, j;
        // 参考代码随想录:区间[起点,终点),左闭右开
        while(0 < loop--){
            // 新的起点
            i = starty;
            j = startx;
            // 模拟上
            for(; j < startx + n - offset; j++)
                res.add(matrix[i][j]);
            //模拟右
            for(; i < starty + m - offset; i++)
                res.add(matrix[i][j]);
            // 模拟下
            for(; j > startx; j--)
                res.add(matrix[i][j]);
            // 模拟左
            for(; i > starty; i--)
                res.add(matrix[i][j]);
            startx++;
            starty++;
            offset += 2; //因为startx和starty也加了1,所以计算边界时需要将加的1减掉
        }
        if(minIdx % 2 == 1){ // 每次走2行2列,所以奇数行或奇数列最后会剩下一行或一列
            // while循环终止导致i和j没有更新
            i = starty;
            j = startx;
            if(m <= n){
                //模拟剩下的一行
                while(j <= startx + n - offset){
                    res.add(matrix[i][j]);
                    j++;
                }
            } else {
                // 模拟剩下的一列
                while(i <= starty + m - offset){
                    res.add(matrix[i][j]);
                    i++;
                }
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值