[Leetcode] Spiral Matrix 螺旋矩阵

450 查看

Spiral Matrix I

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

For example, Given the following matrix:

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

You should return [1,2,3,6,9,8,7,4,5].

顺序添加法

复杂度

时间 O(NM) 空间 O(1)

思路

首先考虑最简单的情况,如图我们先找最外面这圈X,这种情况下我们是第一行找前4个,最后一列找前4个,最后一行找后4个,第一列找后4个,这里我们可以发现,第一行和最后一行,第一列和最后一列都是有对应关系的。即对i行,其对应行是m - i - 1,对于第j列,其对应的最后一列是n - j - 1

XXXXX
XOOOX
XOOOX
XOOOX
XXXXX

然后进入到里面那一圈,同样的顺序没什么问题,然而关键在于下图这么两种情况,一圈已经没有四条边了,所以我们要单独处理,只加那唯一的一行或一列。另外,根据下图我们可以发现,圈数是宽和高中较小的那个,加1再除以2。

OOOOO  OOO
OXXXO  OXO
OOOOO  OXO
       OXO
       OOO

代码

public class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new LinkedList<Integer>();
        if(matrix.length == 0) return res;
        int m = matrix.length, n = matrix[0].length;
        // 计算圈数
        int lvl = (Math.min(m, n) + 1) / 2;
        for(int i = 0; i < lvl; i++){
            // 计算相对应的该圈最后一行
            int lastRow = m - i - 1;
            // 计算相对应的该圈最后一列
            int lastCol = n - i - 1;
            // 如果该圈第一行就是最后一行,说明只剩下一行
            if(i == lastRow){
                for(int j = i; j <= lastCol; j++){
                    res.add(matrix[i][j]);
                }
            // 如果该圈第一列就是最后一列,说明只剩下一列
            } else if(i == lastCol){
                for(int j = i; j <= lastRow; j++){
                    res.add(matrix[j][i]);
                }
            } else {
                // 第一行
                for(int j = i; j < lastCol; j++){
                    res.add(matrix[i][j]);
                }
                // 最后一列
                for(int j = i; j < lastRow; j++){
                    res.add(matrix[j][lastCol]);
                }
                // 最后一行
                for(int j = lastCol; j > i; j--){
                    res.add(matrix[lastRow][j]);
                }
                // 第一列
                for(int j = lastRow; j > i; j--){
                    res.add(matrix[j][i]);
                }
            }
        }
        return res;
    }
}

Spiral Matrix II

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

For example, Given n = 3,

You should return the following matrix:

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

顺序添加法

复杂度

时间 O(NM) 空间 O(1)

思路

本题就是按照螺旋的顺序把数字依次塞进去,我们可以维护上下左右边界的四个变量,一圈一圈往里面添加。最后要注意的是,如果n是奇数,要把中心那个点算上。

代码

public class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        int left = 0, right = n - 1, bottom = n - 1, top = 0, num = 1;
        while(left < right && top < bottom){
            // 添加该圈第一行
            for(int i = left; i < right; i++){
                res[top][i] = num++;
            }
            // 添加最后一列
            for(int i = top; i < bottom; i++){
                res[i][right] = num++;
            }
            // 添加最后一行
            for(int i = right; i > left; i--){
                res[bottom][i] = num++;
            }
            // 添加第一列
            for(int i = bottom; i > top; i--){
                res[i][left] = num++;
            }
            top++;
            bottom--;
            left++;
            right--;
        }
        // 如果是奇数,加上中间那个点
        if(n % 2 == 1){
            res[n / 2][n / 2] = num;
        }
        return res;
    }
}