Go&Java算法之螺旋矩阵

170 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

螺旋矩阵

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

image.png  

示例 1:

输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]] 示例 2:

输入:n = 1 输出:[[1]]  

提示:

1 <= n <= 20

题解

方法一:模拟法(Java)

模拟矩阵的生成。按照要求,初始位置设为矩阵的左上角,初始方向设为向右。若下一步的位置超出矩阵边界,或者是之前访问过的位置,则顺时针旋转,进入下一个方向。如此反复直至填入 n^2个元素。

记 matrix 为生成的矩阵,其初始元素设为 0。由于填入的元素均为正数,我们可以判断当前位置的元素值,若不为 0,则说明已经访问过此位置。

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];

        int num = 1;
        int left = 0;
        int right = n - 1;
        int high = 0;
        int low = n - 1;
        int target = (int) Math.pow(n, 2);

        while (num <= target) {
            for (int i = left; i <= right; i++) {
                res[high][i] = num++;
            }
            high++;
            for (int i = high; i <= low; i++) {
                res[i][right] = num++;
            }
            right--;
            for (int i = right; i >= left; i--) {
                res[low][i] = num++;
            }
            low--;
            for (int i = low; i >= high; i--) {
                res[i][left] = num++;
            }
            left++;
        }

        return res;
    }
}

时间复杂度:O(N^2)

空间复杂度:O(1)

方法二:模拟法(Go)

本题要坚持循环不变量原则。

  • 模拟顺时针画矩阵的过程:
    • 填充上行从左到右
    • 填充右列从上到下
    • 填充下行从右到左
    • 填充左列从下到上

由外向内一圈一圈这么画下去。

这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开又闭的原则,这样这一圈才能按照统一的规则画下来。

本方法按照左闭右开的原则,进行模拟画图。

func generateMatrix(n int) [][]int {
    top, bottom := 0, n-1
    left, right := 0, n-1
    num := 1
    tar := n * n
    matrix := make([][]int, n)
    for i := 0; i < n; i++ {
        matrix[i] = make([]int, n)
    }
    for num <= tar {
        for i := left; i <= right; i++ {
            matrix[top][i] = num
            num++
        }
        top++
        for i := top; i <= bottom; i++ {
            matrix[i][right] = num
            num++
        }
        right--
        for i := right; i >= left; i-- {
            matrix[bottom][i] = num
            num++
        }
        bottom--
        for i := bottom; i >= top; i-- {
            matrix[i][left] = num
            num++
        }
        left++
    }
    return matrix
}

时间复杂度:O(N^2)

空间复杂度:O(1)