螺旋矩阵系列(LeetCode 59,54,剑指 29)

M - 59.螺旋矩阵II 

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

模拟法

从左到右,从上到下,从右到左,从下到上,注意数组的下标方向,特别注意当n是奇数时的边界条件

class Solution {
    public int[][] generateMatrix(int n) {
        //模拟法
        if(matrix == null || matrix.length == 0)
           return new int[0][0];//注意空值情况的判断
        int left = 0, right = n - 1, top = 0, bottom = n - 1;
        int[][] Matrix = new int[n][n];
        int num = 1;
        while(num <= n * n){//使用num <= n * n而不是left < right || top < bottom作为迭代条件,是为了解决当n为奇数时,矩阵中心数字无法在迭代过程中被填充的问题。
            for(int i = left; i <= right; i++, num++)//在top层从左到右移动
                Matrix[top][i] = num;
            top++;
            for(int i = top; i <= bottom; i++, num++)//在right列从上到下移动
                Matrix[i][right] = num;
            right--;
            for(int i = right; i >= left; i--, num++)//在bottom行从右到左移动
                Matrix[bottom][i] = num;
            bottom--;
            for(int i = bottom; i >= top; i--, num++)//在left列从下到上移动
                Matrix[i][left] = num;
            left++;
        }
        return Matrix;
    }
}

 按层模拟

螺旋矩阵是多个正方形组成的层次矩阵,从最外层矩阵开始填充,然后到次层直到最里面的正方形层次,特别注意从右到左和从下到上的走法

class Solution {
    public int[][] generateMatrix(int n) {
        //模拟法
        if(matrix == null || matrix.length == 0)
           return new int[0][0];//注意空值情况的判断
        int left = 0, right = n - 1, top = 0, bottom = n - 1;
        int[][] Matrix = new int[n][n];
        int num = 1;
        while(left <= right && top <= bottom){
            for(int i = left; i <= right; i++, num++)//在top层从左到右移动
                Matrix[top][i] = num;
            for(int i = top + 1; i <= bottom; i++, num++)//在right层从上到下移动
                Matrix[i][right] = num;
            if(left < right && top < bottom){//这个if语句原因是因为每次都是先往右走和先往下走,所以往右走和往下走的路一定是没走过的路,不需要加 if 判断;往左走的时候,如果 top == bottom,那么会重复走之前从左往右走过的路,所以需要加上 top < bottom 的判断,同理往上走也一样。
                for(int i = right - 1; i >= left; i--, num++)//在bottom层从右到左移动
                    Matrix[bottom][i] = num;
                for(int i = bottom - 1; i > top; i--, num++)//在left列从下到上移动,注意循环边界,该层第一个数不能取到
                    Matrix[i][left] = num;
            }
            left++;
            right--;
            top++;
            bottom--;
        }
        return Matrix;
    }
}

 M - 54.螺旋矩阵

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

模拟法

模拟从左到右,从上到下,从右到左,从下到上,注意数组的下标方向,这里行数和列数很有可能不相等,所以特别注意最后一次重复进入for而导致重复走

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        //模拟法
        if(matrix == null || matrix.length == 0)
           return new List<Integer>();//注意空值情况的判断
        int m = matrix.length;//n列数,m行数
        int n = matrix[0].length;
        int left = 0, right = n - 1, top = 0, bottom = m - 1;
        List<Integer> numlist = new ArrayList<Integer>();
        int num = 1;
        while(num <= n * m){           
            for(int i = left; i <= right && num <= n * m; i++, num++)//在top层从左到右移动,添加&& num <= n * m是为了防止只剩从右到左或从下到上重复走,防止到达num后会再次进入for循环而重复走
                numlist.add(matrix[top][i]);
            top++;
            for(int i = top; i <= bottom && num <= n * m; i++, num++)//在right层从上到下移动
                numlist.add(matrix[i][right]);
            right--;
            for(int i = right; i >= left && num <= n * m; i--, num++)//在bottom层从右到左移动
                numlist.add(matrix[bottom][i]);
            bottom--;
            for(int i = bottom; i >= top && num <= n * m; i--, num++)//在left列从下到上移动
                numlist.add(matrix[i][left]);
            left++;           
        }
        return numlist;
    }
}

按层模拟法

 与59相同思路,还是要注意最后一次的走法,这里用num <= n * m的写法,避免重复走循环也要判断num <= n * m

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        //按层模拟法
        if(matrix == null || matrix.length == 0)
           return new List<Integer>();//注意空值情况的判断
        int m = matrix.length;//n列数,m行数
        int n = matrix[0].length;
        int left = 0, right = n - 1, top = 0, bottom = m - 1;
        List<Integer> numlist = new ArrayList<Integer>();
        int num = 1;
        while(num <= n * m){           
            for(int i = left; i <= right && num <= n * m; i++, num++)//在top层从左到右移动,添加&& num <= n * m是为了防止只剩从右到左或从下到上重复走,防止到达num后会再次进入for循环而重复走
                numlist.add(matrix[top][i]);
            for(int i = top + 1; i <= bottom && num <= n * m; i++, num++)//在right层从上到下移动
                numlist.add(matrix[i][right]);            
            for(int i = right - 1; i >= left && num <= n * m; i--, num++)//在bottom层从右到左移动
                numlist.add(matrix[bottom][i]);            
            for(int i = bottom - 1; i > top && num <= n * m; i--, num++)//在left列从下到上移动
                numlist.add(matrix[i][left]);            
            top++;
            right--;
            bottom--;
            left++;           
        }
        return numlist;
    }
}

E - 剑指29 顺时针打印矩阵

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

 按层模拟法

同理注意刚开始边界的判断

class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if(matrix == null || matrix.length == 0)
           return new int[0];//注意空值情况的判断
        int m = matrix.length;        
        int n = matrix[0].length;      
        int l = 0, r = n - 1, t = 0, b = m - 1;
        int[] arr = new int[m * n];
        int num = 0;
        while(num < m * n){
            for(int i = l; i <= r && num < m * n; i++, num++)
                arr[num] = matrix[t][i];
            for(int i = t + 1; i <= b && num < m * n; i++, num++)
                arr[num] = matrix[i][r];
            for(int i = r - 1; i >= l && num < m * n; i--, num++)
                arr[num] = matrix[b][i];
            for(int i = b - 1; i > t && num < m * n; i--, num++)
                arr[num] = matrix[i][l];
            l++;
            r--;
            t++;
            b--;
        }
        return arr;

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值