ACM 选手图解 LeetCode 模拟法解决螺旋矩阵Ⅱ

简介: 给定正整数 n,生成一个包含 1 ~ n² 所有元素,且元素按顺时针螺旋排列的 n * n 正方形矩阵 matrix。

大家好呀,我是你们的螺旋蛋。


今天解决螺旋矩阵Ⅱ,模拟法解决数组的练手好题,面试常见。


这道题没有算法上的难度,考察的是小婊贝们的代码能力和细心水平。


话不多说,正式开干。

image.png

   LeetCode 59:螺旋矩阵Ⅱ



题意



给定正整数 n,生成一个包含 1 ~ n² 所有元素,且元素按顺时针螺旋排列的 n * n 正方形矩阵 matrix。



示例


输入:n = 3

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

解释:

image.png

提示


  • 1 <= n <= 20


题目解析


一道模拟题,难度中等,面试出现频率极高。


模拟题就是本身不涉及算法,就是单纯根据题目所描述的模拟整个过程从而得到最后的结果。


这类题天然的察你的码力,即对编程语言的掌握能力,一不小心就会各种 bug。


做这类模拟题的要点就是多在纸上画一下,别空想把自己想晕了,代码写干净些,方面后面 debug...

image.png


这道题是按“顺时针”顺序对矩阵进行填充,方向无非就是“上下左右”,顺时针的话,填充就是按照“上->右->下->左”,写具体点就是:


  • 上:从左到右填充。
  • 右:从上到下填充。
  • 下:从右到左填充。
  • 左:从下到上填充。


同时找好每次填充的边界,比如最开始的时候最左侧边界 left = 0,最右侧边界 right = n-1,最上侧边界 up = 0,最下侧边界 down = n-1。


此处你应该拿出笔和纸,开始在纸上写写画画了。


理解了上面话,我们来看图解。


图解


以 n = 4 为例。


首先初始化结果矩阵和上下左右边界。

image.png

# 初始化结果矩阵
res = [[0] * n for i in range(n)]
# 维护当前值
cnt = 1
# 初始化左、右、上、下边界。
left, right, up, down = 0, n-1, 0, n-1

接下来按照顺时针顺序填充结果矩阵。


第 1 步最上行从左到右填充:


此时 up = 0,固定不变,从左至右在 [left, right] 间填充。

image.png

# 从左到右
for i in range(left, right + 1):
    res[up][i] = cnt
    cnt += 1

此时最上行被填充完毕,上边界 top 发生了改变,需要向下移动。

image.png

up += 1

第 2 步最右列从上向下填充:


此时 right = n - 1 =3,固定不变,从上至下在 [up, down] 之间填充。

image.png

# 从上到下
for i in range(up, down + 1):
    res[i][right] = cnt
    cnt += 1


此时最右列被填充完毕,右边界 right 发生了改变,需要向左移动。

image.png

right -= 1

第 3 步最下行从右向左填充:


此时 down = n - 1 = 3 固定不变,从右至左在 [left, right] 之间填充。

image.png

# 从右到左
for i in range(right, left-1, -1):
    res [down][i] = cnt
    cnt += 1

此时最下行被填充完毕,下边界 down 发生了改变,需要向上移动。

image.png

down -= 1

第 4 步最左列从下向上填充:


此时 left = 0 固定不变,从下至上在 [up, down] 之间填充。

image.png

# 从下到上
for i in range(down, up-1, -1):
    res[i][left] = cnt
    cnt += 1

此时最左列被填充完毕,左边界 left 发生了改变,需要向右移动。

image.png

left += 1

剩下的步骤就是重复上面 4 步,直到 n² 的数都填完。


本题模拟法矩阵大小为 n²,需要全部遍历且填充,所以时间复杂度为 O(n²)


此外额外维护了一个大小为 n² 的结果矩阵,所以空间复杂度为 O(n²)


代码实现


Python 代码实现

class Solution(object):
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        # 初始化结果矩阵
        res = [[0] * n for i in range(n)]
        # 维护当前值
        cnt = 1
        # 初始化左、右、上、下边界。
        left, right, up, down = 0, n-1, 0, n-1
        while cnt <= n * n:
            # 从左到右
            for i in range(left, right + 1):
                res[up][i] = cnt
                cnt += 1
            up += 1
            # 从上到下
            for i in range(up, down + 1):
                res[i][right] = cnt
                cnt += 1
            right -= 1
            # 从右到左
            for i in range(right, left-1, -1):
                res [down][i] = cnt
                cnt += 1
            down -= 1
            # 从下到上
            for i in range(down, up-1, -1):
                res[i][left] = cnt
                cnt += 1
            left += 1
        return res

Java 代码实现

class Solution {
    public int[][] generateMatrix(int n) {
        int left = 0, right = n - 1, up = 0, down = n - 1;
        int[][] res = new int[n][n];
        int cnt = 1;
        while(cnt <= n * n){
            for(int i = left; i <= right; i++) res[up][i] = cnt++;
            up++;
            for(int i = up; i <= down; i++) res[i][right] = cnt++;
            right--;
            for(int i = right; i >= left; i--) res[down][i] = cnt++; 
            down--;
            for(int i = down; i >= up; i--) res[i][left] = cnt++; 
            left++;
        }
        return res;
    }
}


图解螺旋矩阵Ⅱ
到这就结束辣,是不是模拟法搞的焦头烂额了?


没事,刚接触这样的题都是写一堆 bug,做多了,码力上升了就 ok 了。


多点耐心,多写写画画,一步一步的来。


差不多数组的实战题到这就结束了,基本上每道题都是一种新的解题方法,大家一定要仔细揣摩,多加练习。


还有不要忘了我的点赞和在看呀。


我是帅蛋,我们下次见!







相关文章
|
9月前
【Leetcode -2181.合并零之间的节点- 2326.螺旋矩阵Ⅳ】
【Leetcode -2181.合并零之间的节点- 2326.螺旋矩阵Ⅳ】
54 0
|
26天前
leetcode54螺旋矩阵题解
leetcode54螺旋矩阵题解
12 2
|
1月前
|
算法 机器人 数据挖掘
LeetCode题目54:螺旋矩阵【python4种算法实现】
LeetCode题目54:螺旋矩阵【python4种算法实现】
|
17天前
|
存储 算法
力扣经典150题第三十五题:螺旋矩阵
力扣经典150题第三十五题:螺旋矩阵
7 0
|
9月前
|
机器学习/深度学习 算法
代码随想录Day02 数组基础2 leetcode T977有序数组的平方, T209 长度最小的子数组,T59 螺旋矩阵II
代码随想录Day02 数组基础2 leetcode T977有序数组的平方, T209 长度最小的子数组,T59 螺旋矩阵II
39 0
|
2月前
leetcode-6111:螺旋矩阵 IV
leetcode-6111:螺旋矩阵 IV
28 0
|
2月前
|
Java C++ Python
leetcode-59:螺旋矩阵 II
leetcode-59:螺旋矩阵 II
24 0
|
2月前
leetcode-54:螺旋矩阵
leetcode-54:螺旋矩阵
27 0
LeetCode刷题Day03——数组(滑动窗口+螺旋矩阵)
所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。 滑动窗口也可以理解为双指针法的一种,只不过这种解法更像是一个窗口的移动。 实现滑动窗口,主要确定如下三点:
|
8月前
|
算法
代码随想录算法训练营第二天 | LeetCode 977.有序数组的平方、209.长度最小的子数组、59. 螺旋矩阵 II
代码随想录算法训练营第二天 | LeetCode 977.有序数组的平方、209.长度最小的子数组、59. 螺旋矩阵 II
45 0