Spiral Matrix I/II

需求I:

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

Example :

Input:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]

分析:

顺时针遍历矩阵,可以看成若干次循环,每次循环分成四部分,第一行,第一列,第二行,第二列。假设每一圈的起始坐标是[startx][starty],其实startx==starty,第一行就是[startx][startx]~[startx][endy],第一列就是[startx+1][endy]~[endx][endy],第二行是[endx][endy-1]~[endx][startx],第二列是[endx-1][startx]~[startx+1][startx]。其中,遍历第一行和第一列的时候不需要判断,只有多于一行时才需要遍历第二行,只有多于一列时才需要遍历第二列,所以遍历后两个边的时候需要判断。

每遍历完一圈,需要更新startx,endx和endy,startx++,endx--,endy--,每次循环的圈会更小。遍历结束的条件是rows<=startx*2或者cols<=startx*2。

代码:

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new LinkedList<Integer>();
        
        //异常处理
        if(matrix == null || matrix.length == 0)
            return res;
        
        int rows = matrix.length;//行
        int cols = matrix[0].length;//列
        
        int startx = 0, endx = rows-1, endy = cols-1;
        while(rows > 2*startx && cols > 2*startx){
            //打印第一行
            for(int i = startx; i <= endy; i++)
                res.add(matrix[startx][i]);
            
            //打印第一列
            for(int i = startx+1; i <= endx; i++)
                res.add(matrix[i][endy]);
            
            //如果有多的行,那么就打印第二行
            if(endx > startx){
                for(int i = endy-1; i >= startx; i--)
                    res.add(matrix[endx][i]);
            }
            
            //如果有多列,那么就打印最后一列
            if(endy > startx)
            {
                for(int i = endx-1; i > startx; i--)
                    res.add(matrix[i][startx]);
            }
            
            //每次循环之后,需要更新下次循环的起始和结束位置+
            startx++;
            endx--;
            endy--;
        }
        
        return res;
    }
}

需求II:

Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.

Example:

Input: 3
Output:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]

分析:

和I的区别在于,I是已知矩阵,并且不一定是方阵,求顺时针遍历的结果。II是顺时针填充n*n矩阵。和I思路相似,我们需要创建一个n*n的矩阵,顺时针遍历该数组,依次填充数组。顺时针遍历数组,依旧可以分成若干次循环,每次循环分成四部分,设置一个变量num,从1开始递增,逐步填充矩阵。每遍历完一个圈,需要更新下一个圈的起始和终止坐标,并且要注意整体的循环结束条件。

代码:

class Solution {
    public int[][] generateMatrix(int n) {
        //思路类似于I,对于n,创建n*n的矩阵,顺时针遍历该矩阵,填充数字即可
        //异常处理
        if(n < 0)
            throw new IllegalArgumentException("illegal parameters");
        
        //创建n*n矩阵,初始化为0
        int[][] res = new int[n][n];
        
        //设置每次遍历的起始坐标和结束坐标
        int startx = 0, endx = n-1, endy = n-1;
        int num = 1;//用数字num填充矩阵
        
        while(n > startx * 2){
            //遍历第一行
            for(int i = startx; i <= endy; i++)
                res[startx][i] = num++;
            
            //遍历第一列
            for(int i = startx+1; i <= endx; i++)
                res[i][endy] = num++;
            
            //如果有多行,需要遍历第二行
            if(endx > startx){
                for(int i = endy-1; i >= startx; i--)
                    res[endx][i] = num++;
            }
            
            //如果有多列,需要遍历第二列
            if(endy > startx){
                for(int i = endx-1; i > startx; i--)
                    res[i][startx] = num++;
            }
            
            startx++;
            endx--;
            endy--;
        }
        
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值